网络编程 : 几种语言使用 Socket 实现 TCP
文章目录
- 写在前面
- 内容
- API
- C
- Java
- Socket
- ServerSocket
- Dart
- 代码示例
- C
- 服务端
- 客户端
- Java
- 服务端
- 客户端
- Dart
- 参考
写在前面
在编程里,我们使用 Socket 来实现 TCP 或 UDP 的通信,Socket 是对它们的上层封装。虽然是不同的语言,但它们的 API 接口都遵循一致的逻辑。本篇主要是使用不同语言(C、Java 和 Dart),通过其 Socket API 来实现一个简单的 TCP 通信进行记录。
内容
API
这里主要罗列几种语言使用 Socket 时的几个基本 API,能够完成一个大致的流程。
C
在 C 语言的sys/socket.h
头文件里定义了使用 Socket 的几个 API ,分别是:
int socket(int domain , int type , int protocol);
- 创建套接字
int bind(int sockfd , struct sockaddr *myaddr , socklen_t addrlen);
- 绑定 IP 地址和端口(服务端调用)
int listen(int sockfd , int backlog);
- 进入等待连接请求状态(服务端使用)
int accept(int sockfd , struct sockaddr *addr , socklen_t * addrlen);
- 受理客户端连接请求(服务端使用)
int connect(int sockfd , struct sockaddr *serv_addr , socklen_t addrlen);
- 客户端请求连接(客户端调用)
ssize_t write(int fd , const void * buf , size_t nbytes);
- 写数据
ssize_t read(int fd , void * buf , size_t nbytes);
- 读数据
int close(int fd);
- 关闭
不管是客户端还是服务端,C 语言里都是先使用 socket()
进行创建。
Java
Java 里创建 Socket 的时候,客户端和服务端会使用不同的类,客户端使用的是 Socket
类,服务端使用的是ServerSocket
类
Socket
Socket()
- 创建套接字
public void connect(SocketAddress endpoint)
- 连接到服务端
public InputStream getInputStream()
- 获取输入流(服务端传来的)
public OutputStream getOutputStream()
- 获取输出流(用于传数据给服务端)
public synchronized void close()
- 关闭 Socket(同时会关闭其输入流和输出流)
ServerSocket
ServerSocket()
- 创建套接字
public void bind(SocketAddress endpoint)
- 绑定 IP 地址和端口
public Socket accept()
- 监听连接的到来,并获取到一个新的 Socket,这个 Socket 就是客户端的操作对象
public void close()
- 关闭 Socket
因为服务端通过accept()
拿到了操作客户端的对象,所以输入输出也就对应Socket
的 API。
Dart
待续
代码示例
C
服务端
echo_sever.c#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>#define BUF_SIZE 1024
void error_handling(char *message);int main(int argc, char const *argv[])
{int serv_sock;int clnt_sock;struct sockaddr_in serv_addr;struct sockaddr_in clnt_addr;socklen_t clnt_addr_size;int str_len, i;char message[]="hello world!";if(argc != 2){printf("Usage : %s <port>\n", argv[0]);exit(1);}serv_sock = socket(PF_INET , SOCK_STREAM , 0);if(serv_sock == -1){error_handling("socket() error");}memset(&serv_addr , 0 , sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);serv_addr.sin_port = htons(atoi(argv[1]));if(bind(serv_sock , (struct sockaddr*) &serv_addr , sizeof(serv_addr)) == -1){error_handling("bind() error");}if(listen(serv_sock , 5) == -1){error_handling("listen() error");}clnt_addr_size = sizeof(clnt_addr);for (int i = 0; i < 5; i++){clnt_sock = accept(serv_sock , (struct sockaddr*)&clnt_addr , &clnt_addr_size);if(clnt_sock == -1){error_handling("accept() error");}else{printf("Connected client %d \n" , i+1);}while((str_len = read(clnt_sock , message , BUF_SIZE)) != 0){write(clnt_sock , message , str_len);}close(clnt_sock);}close(serv_sock);return 0;
}void error_handling(char *message){fputs(message , stderr);fputc('\n' , stderr);exit(1);
}
客户端
echo_client.c#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>#define BUF_SIZE 1024
void error_handling(char *message);int main(int argc, char const *argv[])
{int sock;struct sockaddr_in serv_addr;char message[30];int str_len;if(argc != 3){printf("Usage : %s <IP> <port>\n", argv[0]);exit(1);}sock = socket(PF_INET , SOCK_STREAM , 0);if(sock == -1){error_handling("socket() error");}memset(&serv_addr , 0 , sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = inet_addr(argv[1]);serv_addr.sin_port = htons(atoi(argv[2]));if(connect(sock , (struct sockaddr*)&serv_addr , sizeof(serv_addr)) == -1){error_handling("connect() error");}else{puts("Connected............");}while(1){fputs("Input message(Q to quit): " , stdout);fgets(message , BUF_SIZE , stdin);if(!strcmp(message , "q\n") || !strcmp(message , "Q\n")){break;}write(sock , message , strlen(message));str_len = read(sock , message , BUF_SIZE-1);message[str_len] = 0;printf("Message from server : %s \n", message);}close(sock);return 0;
}void error_handling(char *message){fputs(message , stderr);fputc('\n' , stderr);exit(1);
}
Java
服务端
public class Server {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(2000);System.out.println("服务器准备就绪");System.out.println("服务端信息 : " + serverSocket.getInetAddress() + " P : " + serverSocket.getLocalPort());// 等待客户端连接for (; ; ) {// 得到客户端Socket clientSocket = serverSocket.accept();// 构建异步线程用于处理多个到来的客户端ClientHandler clientHandler = new ClientHandler(clientSocket);clientHandler.start();}}// 定义一个线程类private static class ClientHandler extends Thread {private Socket socket;private boolean flag = true;public ClientHandler(Socket socket) {this.socket = socket;}@Overridepublic void run() {super.run();System.out.println("新客户端连接 : " + socket.getInetAddress() + " P : " + socket.getPort());try {// 得到打印流,用于数据输出;服务器回送数据使用PrintStream socketOutput = new PrintStream(socket.getOutputStream());// 得到输入流,用于接收数据BufferedReader socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));do {// 从客户端拿到数据String str = socketInput.readLine();if ("bye".equalsIgnoreCase(str)) {flag = false;// 回送 byesocketOutput.println("bye");} else {System.out.println(str);socketOutput.println("接收到的数据长度为 : " + str.length());}} while (flag);socketInput.close();socketOutput.close();} catch (Exception e) {System.out.println("连接异常断开");} finally {// 关闭连接try {socket.close();} catch (IOException e) {e.printStackTrace();}}System.out.println("客户端已关闭 : " + socket.getInetAddress() + " P : " + socket.getPort());}}
}
客户端
public class Client {public static void main(String[] args) throws IOException {Socket socket = new Socket();socket.setSoTimeout(3000);socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000), 3000);System.out.println("已发送服务器连接");System.out.println("客户端信息 : " + socket.getLocalAddress() + " P : " + socket.getLocalPort());System.out.println("服务端信息 : " + socket.getInetAddress() + " P : " + socket.getPort());try {todo(socket);} catch (Exception e) {System.out.println("异常关闭");}socket.close();socket.shutdownInput();System.out.println("客户端已退出");}private static void todo(Socket client) throws IOException {// 构建键盘输入流InputStream systemInputStream = System.in;BufferedReader inputReader = new BufferedReader(new InputStreamReader(systemInputStream));// 得到 Socket 输入流,并转换为打印流OutputStream outputStream = client.getOutputStream();PrintStream socketPrintStream = new PrintStream(outputStream);// 获取 Socket 输入流,即服务端输入进来的InputStream inputStream = client.getInputStream();BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(inputStream));// 轮询boolean flag = true;do {// 键盘读取一行String str = inputReader.readLine();// 发送到服务器socketPrintStream.println(str);// 从服务器读取一行String echo = socketBufferedReader.readLine();if ("bye".equalsIgnoreCase(echo)) {flag = false;} else {System.out.println(echo);}} while (flag);// 资源释放socketPrintStream.close();socketBufferedReader.close();}
}
Dart
待续
参考
《TCP/IP网络编程》
网络编程 : 几种语言使用 Socket 实现 TCP相关推荐
- [python学习] 专题七.网络编程之套接字Socket、TCP和UDP通信实例
很早以前研究过C#和C++的网络通信,参考我的文章: C#网络编程之Tcp实现客户端和服务器聊天 C#网络编程之套接字编程基础知识 ...
- Python网络编程-一文厘清socket、TCP和UDP那点事
文章目录 网络基础 网络协议 IP地址与端口 socket套接字 概念 Python中socket模块 TCP下的服务器与客户端 TCP工作原理 TCP服务器的实现 TCP客户端的实现 UDP下的服务 ...
- 编程每种语言有什么用_每种情况的最佳编程语言
编程每种语言有什么用 有一个问题,很多人都认为提问者根本不理解该主题. 有些人甚至觉得它很生气. 问题的形式通常是什么是最佳X? 什么是最好的车? 最好的编程语言是什么? 但是同时,这是一个问题,我们 ...
- 少儿编程几种语言_您使用了几种编程语言?
少儿编程几种语言 机器说一种语言,但是人类却说多种不同的语言...编程语言,从Python到JavaScript等等. 一切始于Grace Hopper. "该语言中最具破坏力的短语是: 一 ...
- 网络编程套接字(Socket编程)
Socket:Socket套接字,是由系统提供用于网络通信的技术,是基于TCP/IP协议的网络通信的基本操作单元. Socket API 分类: 1.UDP数据报套接字编程: DatagramSock ...
- 网络编程+go+java_GO语言的进阶之路-网络编程之socket
GO语言的进阶之路-网络编程之socket 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是socket; 在说socket之前,我们要对两个概念要有所了解,就是IP和端口 ...
- socket网络编程常用C语言api函数(Linux)
参考<Linux高性能服务器编程> 网络编程常用函数 字节序 ip转换 地址结构体 socket相关函数 数据读写 获取地址信息 获取或者设置套接字属性 通过域名或地址获取主机信息 字节序 ...
- Linux网络编程 五种I/O 模式及select、epoll方法的理解
近期一次面试机会让我觉得有很多地方理解可能不到位,翻翻谷歌的资料加深对一些技术的理解 五种I/O 模式: [1] 阻塞 I/O (Linux下的I/O操作默认是阻塞I/O,即open和socket创建 ...
- Java之初步识别网络编程:IP、端口号、TCP/UDP、Socket、URL等
文章目录 一.网络编程概述 二.网络通信要素概述 三.通信要素1:IP和端口号 IP相关 InetAdress类 如何实例化InetAddress 端口号 四.通信要素2:网络协议 TCP/IP协议簇 ...
最新文章
- Windows Phone开发(36):动画之DoubleAnimation 转:http://blog.csdn.net/tcjiaan/article/details/7521388...
- STM32时钟源时钟系统配置
- 【机器学习_4】机器学习算法分类
- python next day_PYTHON养成日记 DAY-13
- 复利计算再升级——连接数据库
- 世界上最长的博士论文,列入吉尼斯世界纪录
- java私有变量和_java – 大内部类和私有变量
- Linux源码安装pgadmin4,Linux 服务器部署 PgAdmin 4 Server
- 基于JAVA+SpringMVC+Mybatis+MYSQL的学生请假管理系统
- 【毕业答辩】别小看毕业答辩PPT,它和你的论文一样重要
- python设置字符编码_python字符编码问题一则
- 博客园添加背景音乐,给你的博文加点料
- Hive教程(02)- Hive安装
- multi task训练torch_torch中创建multitask网络结构
- 5线上模式刷2亿bug_GTA5还想冲销量?玩家利用BUG刷钱,遭受比封号更严厉惩罚
- 【极客学院】-iOS学习笔记-2-Xcode(安装,创建项目,工作空间)
- QQ浏览器登陆微信后,下载接收的文件保存在了哪里
- 细观Google全面大揭秘
- Git 修改 commit author
- 全国计算机自考应用题,近几年度自考管理系统中计算机硬应用题汇总.doc
热门文章
- mysql general error,mysql General error: 1267 Illegal mix of collations错误​
- ajax unauthorized,七牛fetch接口抓取第三方资源(网络图片),Js写ajax请求返回error错误信息总是“Unauthorized”...
- 1582年10月5日是个很奇怪的日子
- 程序员猪队友,差到大家都害怕他提交代码...
- Java程序员认证考试 ---SUN认证
- [转]对于WOW商业系统的回顾
- # 前端基础(HTML + CSS + JavaScript)
- 欢迎使用CSDN-markdown编辑器顶顶顶顶顶顶顶顶顶顶
- linux 获取文件名函数,Linux shell中提取文件名和路径
- 32位的SSDT表结构浅析