TCP协议(20250304)
1. TCP
TCP: 传输控制协议(Transmission Control Protocol),传输层协议之一(TCP,UDP)
2. TCP与UDP
UDP(用户数据报协议)
- 面向数据报
- 无连接
- 不安全不可靠(尽最大努力交付)
- 机制简单,传输效率高
TCP(传输控制协议)
- 需要建立连接
- 安全、可靠
- 面向字节流
- 占用资源开销大
3. 三次握手
指建立tcp连接时,需要客户端和服务端总共发送三次报文确认连接
4. 四次挥手
断开一个tcp连接,需要客户端和服务端发送四个报文以确认断开
TCP编程:基于C/S模型的socket文件进行通信
5. TCP框架设计
- client: socket--->connect--->send/write--->close
- server: socket--->bind--->listen--->accept---> recv/read--->close
6. 函数接口
6.1 socket
socket(AF_INET, SOCK_STREAM, 0);
6.2 connect
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:
发送三次握手链接请求
参数:
sockfd:套接字文件描述符
addr:存放目的地址空间首地址
addrlen:目的地址长度
返回值:
成功返回0
失败返回-1
6.3 send
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:
发送数据
参数:
sockfd:套接字文件描述符
buf:存放数据空间首地址
len:数据长度
flag:属性默认为0
返回值:
成功返回发送字节数
失败返回-1
6.4 recv
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能:
接收数据
参数:
sockfd:套接字文件描述符
buf:存放数据空间首地址
len:最多接收数据长度
flags:接收属性默认为0
返回值:
成功返回实际接收字节数
失败返回-1
连接断开返回0
6.5 bind
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
6.6 listen
int listen(int sockfd, int backlog);
功能:
监听三次握手链接请求
参数:
sockfd:套接字文件描述符
backlog:最多允许等待尚未处理的三次握手链接个数
返回值:
成功返回0
失败返回-1
6.7 accept
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:
处理三次握手等待队列中的第一个请求并建立一个用来通信的新套接字
参数:
sockfd:套接字文件描述符
addr:存放发送端IP地址空间首地址
addrlen:想要接收的IP地址的长度
返回值:
成功返回新文件描述符
失败返回-1
7. TCP粘包
TCP协议是面向字节流的协议,接收方不知道消息的界限,不知道一次提取多少数据,这就造成了粘包问题
产生原因
- TCP发送数据时,没有及时发走,会根据缓冲区数据的情况进行重新组包
- TCP接收方,没有及时读走缓冲区数据,导致缓冲区大量数据缓存
解决方案
- 消息定长法:对于定长的包,保证每次都按固定大小读取即可 // 结构体
- 添加消息头:在每个数据包前添加固定长度的消息头,消息头中记录数据包的长度等信息。发送方发送数据时,先发送消息头,再发送实际数据。接收方先读取消息头,获取数据包长度信息,再根据该长度读取后续的实际数据
- 特殊字符分隔法:在数据包之间添加特殊的分隔字符(‘\n’),发送方发送数据时,在每个数据包后加上分隔字符,接收方按分隔字符来分割数据包
8. TCP报文头
标志位:
- URG: 紧急指针标志, 为1时表示紧急指针有效, 该报文应该优先传送。
- ACK: 确认应答标志
- PSH: 表示发送数据,提示接收端从TCP接收缓冲区中读走数据,为接收后续数据腾出空间
- RST: 重置连接标志
- SYN: 表示请求建立一个连接
- FIN: finish标志, 表示释放连接
滑动窗口大小:是TCP流量控制得一个手段。目的是告诉对方,本端的TCP接受缓冲区还能容纳多少字节得数据,这样对方就可以控制发送数据的速度,从而达到流量控制,16bit,因而窗口最大65535
9. TCP机制
保证可靠性的同时又要尽可能的提高性能
可靠性:
- 三次握手和四次挥手机制
- 应答机制:TCP将每个字节的数据都进行了编号,即为序列号。每一个ACK都带有对应的确认序列号,保证数据不丢失的按序到达
- 超时重传:当发送端发送的数据在网络中丢失时,在一定时间内没有收到接收端的ACK,则发送端会重新发送丢失数据。
- 流量控制:按照ACK中“窗口大小”字段控制发送端的发送速度
提高性能:
- 滑动窗口:可以按照“窗口大小”, 一次发送多条后, 再等待应答
- 延迟应答:当接收方处理速度很快时,可以延迟发送ACK,此时"窗口大小"会自动增大
- 捎带应答:搭载应用层的响应报文发送ACK