tcpip协议使用"流式"(套接字)进行数据的传输,就是说它保证数据的可达以及数据抵达的顺序,但并不保证数据是否在你接收的时候就到达,特别是为了提高效率,充分利用带宽,底层会使用缓存技术,具体的说就是使用Nagle算法将小的数据包放到一起发送,但是这样也带来一个使用上的问题——黏包,黏包就是说一次将多个数据包发送出去,导致接收方不能进行正常的解析,示意图如下:
万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

发生黏包一般有两种原因,一种是发送方进行了不该缓冲的缓冲,比如上图中,收发双方协议好按照一定的规则进行编写/解析报文,但是由于Nagle算法,可能出现发送方一次发送了1.5个数据包,而接收方只解析了前面的1个包,后面的0.5个由于数据不完整而解析失败,造成数据的丢失或错位,很可能会影响之后所有的数据解析工作。由于发送方导致的黏包问题可以使用setsockopt()来解决

int enable=1;setsockopt(sockfd,IPROTO_TCP,TCP_NODELAY,(void*)&enable,sizeof(enable))

这条指令可以禁止发送方使用Nagle算法,一组数据被写入就会立即被发出,不需要等待mtu被填满。

此外,接收方处理不当也可能导致黏包问题,如果发送方将4个包发送到接收方的缓冲区,但是由于频繁的存取,可能有一次只取了2.5个包,就会导致黏包问题。接收方的黏包问题可以使用recv(sockfd

网友评论