Netty之TCP粘包拆包问题
2016-12-15 22:43
369 查看
粘包拆包问题是处于网络比较底层的问题,在数据链路层、网络层以及传输层都有可能发生。我们日常的网络应用开发大都在传输层进行,由于UDP有消息保护边界,不会发生这个问题,因此这篇文章只讨论发生在传输层的TCP粘包拆包问题。
什么是粘包、拆包?
对于什么是粘包、拆包问题,我想先举两个简单的应用场景:客户端和服务器建立一个连接,客户端发送一条消息,客户端关闭与服务端的连接。
客户端和服务器简历一个连接,客户端连续发送两条消息,客户端关闭与服务端的连接。
对于第一种情况,服务端的处理流程可以是这样的:当客户端与服务端的连接建立成功之后,服务端不断读取客户端发送过来的数据,当客户端与服务端连接断开之后,服务端知道已经读完了一条消息,然后进行解码和后续处理...。对于第二种情况,如果按照上面相同的处理逻辑来处理,那就有问题了,我们来看看第二种情况下客户端发送的两条消息递交到服务端有可能出现的情况:
第一种情况:
服务端一共读到两个数据包,第一个包包含客户端发出的第一条消息的完整信息,第二个包包含客户端发出的第二条消息,那这种情况比较好处理,服务器只需要简单的从网络缓冲区去读就好了,第一次读到第一条消息的完整信息,消费完再从网络缓冲区将第二条完整消息读出来消费。第二种情况:
服务端一共就读到一个数据包,这个数据包包含客户端发出的两条消息的完整信息,这个时候基于之前逻辑实现的服务端就蒙了,因为服务端不知道第一条消息从哪儿结束和第二条消息从哪儿开始,这种情况其实是发生了TCP粘包。第三种情况:
服务端一共收到了两个数据包,第一个数据包只包含了第一条消息的一部分,第一条消息的后半部分和第二条消息都在第二个数据包中,或者是第一个数据包包含了第一条消息的完整信息和第二条消息的一部分信息,第二个数据包包含了第二条消息的剩下部分,这种情况其实是发送了TCP拆,因为发生了一条消息被拆分在两个包里面发送了,同样上面的服务器逻辑对于这种情况是不好处理的。为什么会发生TCP粘包、拆包呢?
发生TCP粘包、拆包主要是由于下面一些原因:
应用程序写入的数据大于套接字缓冲区大小,这将会发生拆包。应用程序写入数据小于套接字缓冲区大小,网卡将应用多次写入的数据发送到网络上,这将会发生粘包。
进行MSS(最大报文长度)大小的TCP分段,当TCP报文长度-TCP头部长度>MSS的时候将发生拆包。
接收方法不及时读取套接字缓冲区数据,这将发生粘包。
……
如何处理粘包、拆包问题?
知道了粘包、拆包问题及根源,那么如何处理粘包、拆包问题呢?TCP本身是面向流的,作为网络服务器,如何从这源源不断涌来的数据流中拆分出或者合并出有意义的信息呢?通常会有以下一些常用的方法:使用带消息头的协议、消息头存储消息开始标识及消息长度信息,服务端获取消息头的时候解析出消息长度,然后向后读取该长度的内容。
设置定长消息,服务端每次读取既定长度的内容作为一条完整消息。
设置消息边界,服务端从网络流中按消息编辑分离出消息内容。
……
原博客地址
https://my.oschina.net/andylucc/blog/625315
相关文章推荐
- Netty解决半包(TCP粘包/拆包导致)读写问题
- Netty实践(二):TCP拆包、粘包问题
- java netty使用DelimiterBasedFrameDecoder处理tcp粘包问题
- netty开发之tcp粘包拆包问题
- Netty之TCP粘包拆包问题
- Netty通信框架提供解决TCP粘包拆包问题方案
- netty解决TCP网络传输中的拆包与粘包问题
- Netty中使用MessagePack时的TCP粘包问题与解决方案
- Netty解决半包(TCP粘包/拆包导致)读写问题
- Netty系列-TCP粘包拆包问题
- 基于Netty解决TCP的粘包拆包问题
- 【第13章】【TCP粘包/拆包问题和Netty的解决方案】
- Netty3.10.1:关于TCP粘包问题 及 Encoder&Decoder
- Netty解决半包(TCP粘包/拆包导致)读写问题
- Netty解决半包(TCP粘包/拆包导致)读写问题
- Netty精粹之TCP粘包拆包问题
- Netty高级(Netty5.0的用法,TCP粘包、拆包问题解决方案)
- Netty学习——TCP粘包/拆包的问题
- netty源码分析(二十五)Netty自定义协议与TCP粘包拆包问题解决之道
- Netty学习总结(5)——Netty之TCP粘包/拆包问题的解决之道