自修之道莫难于养心!
目录
11. 套接字编程 (Socket)
11.1 UDP (User Datagram Protocol) 用户数据报协议
11.1.1 流程
客户端
1. 创建 socket 文件描述符
- int socket(int domain, int type, int protocol);
- domain:地址域,AF_INET_IPV4地址域
- type:套接字类型 socket_STEAM: 流式套接字 socket_DGRAM: 数据报套接字
- protocol: 传输层协议类型 0–默认 IPPROTO_IPC 6 IPPROTO_udp 17
- 返回值:套接字操作句柄 – 文件描述符
2. 绑定端口号 (客户端不推荐主动绑定,发送数据的时候能够表述从哪个端口号发送出去,
回复数据时就会再回复到这个地址端口上)
- int bind(int socket, const struct sockaddr *address,socklen_t address_len);
3.发送数据(将 data 中 dlen 长度的数据通过 sockfd 对应的 socket 结构中的ip/端口将数据发
送到dest_addr地址的主机上)
- sendto(sockfd,data,dlen,flag,dest_addr,addr_len);
4.接受数据(从socket对应的socket结构体中的接受队列中取出一条数据放到buf中)
- recvfrom(sockfd,buf,len,flag,&peer_addr,&addr_len);
5.关闭套接字
- int close();
服务端
1. 创建 socket 文件描述符
- int socket(int domain, int type, int protocol);
2. 绑定端口号 (客户端不推荐主动绑定,发送数据的时候能够表述从哪个端口号发送出去,
回复数据时就会再回复到这个地址端口上)
- int bind(int socket, const struct sockaddr *address,socklen_t address_len);
3.接受数据(从socket对应的socket结构体中的接受队列中取出一条数据放到buf中)
- recvfrom(sockfd,buf,len,flag,&peer_addr,&addr_len);
4.发送数据(将data中dlen长度的数据通过sockfd对应的socket结构中的ip/端口将数据发
送到dest_addr地址的主机上)
- sendto(sockfd,data,dlen,flag,dest_addr,addr_len);
5.关闭套接字
- int close();
11.1.2 适用场景
实时性要求极高, 但是安全性要求不是很高的场景 (例如视频传输)
11.1.3 特点
传输层协议, 无连接, 不可靠传输, 面向数据报
11.2 TCP (Transmission Control Protocol) 传输控制协议
11.2.1 流程
客户端
1. 创建 socket 文件描述符
- int socket(int domain, int type, int protocol);
2. 绑定端口号 (客户端不推荐主动绑定,发送数据的时候能够表述从哪个端口号发送出去,回复数据时就会再回复到这个地址端口上)
- int bind(int socket, const struct sockaddr *address,socklen_t address_len);
3.向服务端发起连接请求
- connect(socketfd,srv_addr,addrlen);
4.发送数据(将 data 中 dlen长度的数据通过 sockfd 对应的 socket 结构中的ip/端口将数据发送到dest_addr地址的主机上)
- sendto(sockfd,data,dlen,flag);
5.接受数据(从 socket 对应的 socket 结构体中的接受队列中取出一条数据放到buf中)
- recvfrom(sockfd,buf,dlen,flag);
6.关闭套接字
- int close();
服务端
1. 创建 socket 文件描述符
- int socket(int domain, int type, int protocol);
2. 绑定端口号 (客户端不推荐主动绑定,发送数据的时候能够表述从哪个端口号发送出去,回复数据时就会再回复到这个地址端口上)
- int bind(int socket, const struct sockaddr *address,socklen_t address_len);
3. 开始监听(告诉操作系统若是有的新的客户端连接请求过来了,就是为这个客户端完成三次握手建立连接的过程)
- backlog: 客户端的最大并发连接数
- listen(sockfd,int backlog);
4. 获取已完成连接
5. 通过获取的已完成连接socket接收数据
6. 通过获取得已完成连接socket发送数据
7. 关闭套接字
- int close();
11.2.2 适用场景
安全性要求极高的场景 (文件传输)
11.2.3 特点
传输层协议, 有连接, 可靠传输, 面向字节流
11.2.4 TCP服务端缺陷
- TCP服务端为每个客户端都新建套接字进行独立通信,但是服务端无法获知哪个客户端数据会先到来, 因此可能会阻塞在等待连接请求或者等待接收某个客户端数据。
11.2.5 解决方案
- 多进程,多线程任务处理;
- 每个线程、进程独立负责一个功能;
- 一个线程、进程复制客户端已完成连接获取功能;
- 为每个客户端都建立一个线程,进程处理独立通信。