对于第一种情况,服务器的处理流程可以是这样的:当客户端与服务器的连接建立成功以后,服务器不断读取客户端发送过来的数据,当客户端与服务器连接断开以后,服务器知道已经读完了一条消息,然后进行解码和后续处理。对于第二种情况,如果按照上面相同的处理逻辑来处理,那就有问题了,我们来看看第二种情况下客户端发送的两条消息递交到服务端有可能出现的情况:
服务器一共读到两个数据包,第一个包包含客户端发出的第一条消息的完整信息,第二个包包含客户端发出的第二条消息,那这种情况比较好处理,服务器只需要简单的从网络缓冲区去读就好了,第一次读到第一条消息的完整信息,消费完再从网络缓冲区将第二条完整消息读出来消费。
服务器一共就读到一个数据包,这个数据包包含客户端发出的两条消息的完整性,这个时候基于之前逻辑实现的服务器就懵了。因为服务器不知道第一条消息从哪结束以及第二条消息从哪开始,这是发生了TCP粘包。
服务器一共收到了两个数据包,
第一个数据包只包含了第一条消息的一部分,第一条消息的后半部分和第二条消息都在第二个数据包中;
或者第一个数据包包含了第一条消息的完整信息和第二条消息的一部分信息,第二个数据包包含了第二条消息的剩下部分,这种情况其实是发送了TCP拆包。
因为发生了一条消息被拆分在了两个包里面发送了,同样上面的服务器逻辑对于这种情况是不好处理的。
我们知道TCP是以流动的方式传输数据的,传输的最小单位为一个报文段(Segment)。TCP Header中有个Options标识位。常见的标识位为MSS(Maximum Segment Size)指的是,连接层每次传输的数据有个最大限制MTU()
原文:https://www.cnblogs.com/Roni-i/p/11218535.html