在TCP的socket编程中,发送端和接收端都有成对的socket。发送端为了将多个发往接收端的包,更加高效的的发给接收端,于是采用了优化算法(Nagle算法),将多次间隔较小、数据量较小的数据,合并成一个数据量大的数据块,然后进行封包。那么这样一来,接收端就必须使用高效科学的拆包机制来分辨这些数据。 TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。 (1) 发送方原因
TCP默认使用Nagle算法(主要作用:减少网络中报文段的数量), 而Nagle算法主要做两件事:
只有上一个分组得到确认,才会发送下一个分组
收集多个小分组,在一个确认到来时一起发送
Nagle算法造成了发送方可能会出现粘包问题
(2) 接收方原因
TCP接收到数据包时,并不会马上交到应用层进行处理,或者说应用层并不会立即处理。实际上,TCP将接收到的数据包保存在接收缓存里,然后应用程序主动从缓存读取收到的分组。这样一来,如果TCP接收数据包到缓存的速度大于应用程序从缓存中读取数据包的速度,多个包就会被缓存,应用程序就有可能读取到多个首尾相接粘到一起的包。
TCP产生拆包和粘包的原因:
1、TCP 是基于字节流的,虽然应用层和 TCP 传输层之间的数据交互是大小不等的数据块,但是 TCP 把这些数据块仅仅看成一连串无结构的字节流,没有边界;
2、从 TCP 的帧结构也可以看出,在 TCP 的首部没有表示数据长度的字段。
下面是几种解决TCP粘包问题的方法:
1、使用消息定界符:在每个消息的结尾添加一个特定的字符或者字符序列作为消息的定界符。接收方可以根据定界符判断消息的结束位置,从而正确地解析消息。
2、使用消息长度:在每个消息的开头添加一个指定长度的字段,用于表示消息的总长度。接收方首先读取该字段,然后根据长度读取对应的消息,从而正确地解析消息。
3、使用固定长度的消息:如果每个消息的长度都是固定的,那么接收方可以按照固定长度读取数据,从而正确地解析消息。
4、使用分隔符:可以在每个消息之间添加一个分隔符,例如换行符、制表符等。接收方可以根据分隔符判断消息的结束位置,从而正确地解析消息。
5、应用层协议设计:在设计应用层协议时,可以将每个消息分为消息头和消息体两部分。消息头中包含消息的长度等信息,接收方首先读取消息头,然后根据消息长度读取消息体,从而正确地解析消息。
6、使用TCP_NODELAY选项:将TCP_NODELAY选项设置为1,可以禁用Nagle算法,从而避免数据包在发送缓冲区中积累过多,减少粘包的发生。
标签:TCP,粘包,发送,消息,解决,长度,接收 From: https://www.cnblogs.com/lyfily-p-7439305/p/17466539.html