TCP粘包拆包的逻辑情景:
客户端与服务器建立连接,客户端发送一条或多条数据,客户端关闭与服务端的连接。
针对发送一条数据:断开连接后,服务端知道已经读完一条消息,然后进行解码和后续处理
针对发送多条数据:
断开连接后,可能出现粘包拆包问题。
正常情况:服务端读到第一条数据的完整信息,消费完后再从网络缓冲区将第二条完整消息读出来消费。
粘包情况:服务端一共读取了一条数据包,这个数据包包含了客户端发出的两条消息的完整信息,此时服务端不知道消息的结束点和开始点,发生粘包。
拆包情况:假设两条数据,服务端一共收到了两个数据包,第一个数据包包含了第一条消息的一部分,第二个数据包包含了第一条消息的剩下部分以及第二条消息的全部,发生拆包。
发生粘包拆包的原因:
1,应用程序写入的数据大于套接字缓冲区的大小---拆包
2,应用程序写入的数据小于套接字缓冲区的大小,网卡将应用多次写入的数据发送到网络上---粘包
3,进行MSS(最大报文长度)大小的TCP分段,当TCP报文长度-TCP头部长度>MSS的时候---拆包
4,接收方法不及时读取套接字缓冲区数据---粘包
如何处理粘包拆包问题:
1,使用带消息头的协议,消息头存储消息开始标识及消息长度信息,服务端获取消息头的时候解析出消息长度,然后向后读取该消息的长度
2,设置定长消息,服务端每次读完既定长度的内容作为一条完整消息
3,设置消息边界,服务端从网络流中按消息边界分离出消息内容
后续会研究netty...
内容自公众号: java高级部落