TCP是一个面向字节流的传输层协议。“流” 意味着 TCP 所传输的数据是没有边界的。这不同于 UDP 协议提供的是面向消息的传输服务,其传输的数据是有边界的。TCP 的发送方无法保证对方每次收到的都是一个完整的数据包。于是就有了粘包、拆包问题的出现。粘包、拆包问题只发生在TCP协议中。
TCP协议是面向字节流的协议,接收方不知道消息的界限,不知道一次提取多少数据,这就造成了粘包问题。
粘包问题出现的原因:
1. 发送端:需要等缓冲区满时才发送出去,造成粘包;
2. 接收端:不及时的接收缓冲区内的包,造成多个包接收。
避免粘包问题的方法:
1. 对于定长的包,保证每次都按固定大小读取即可;// 结构体
2. 对于变长的包,还可以在包和包之间使用明确的分隔符,这个分隔符是由程序员自己来定的,只要保证分隔符不和正文冲突即可。
TCP报文头
标志位:
1. URG: 紧急指针标志, 为1时表示紧急指针有效, 该报文应该优先传送。
2. ACK: 确认应答标志
3. PSH: 表示发送数据,提示接收端从TCP接收缓冲区中读走数据,为接收后续数据腾出空间
4. RST: 重置连接标志
5. SYN: 表示请求建立一个连接
6. FIN: finish标志, 表示释放连接
TCP的机制
TCP复杂是因为它既要保证可靠性,同时又要尽可能的提高性能。
可靠性:
(1)三次握手和四次挥手机制
(2) 确认应答:TCP将每个字节的数据都进行了编号,即为序列号。每一个ACK都带有对应的确认序列号,保证数据不丢失的按序到达
(3)超时重传:当发送端发送的数据在网络中丢失时,在一定时间内没有收到接收端的ACK,则发送端会重新发送丢失数据。
(4)流量控制:按照ACK中“窗口大小”字段控制发送端的发送速度