TCP粘包拆包问题
来源:互联网 发布:sybase数据库访问 编辑:程序博客网 时间:2024/05/29 04:10
粘包拆包问题是处于网络比较底层的问题,在数据链路层、网络层以及传输层都有可能发生。我们日常的网络应用开发大都在传输层进行,由于UDP有消息保护边界,不会发生这个问题,因此这篇文章只讨论发生在传输层的TCP粘包拆包问题。
什么是粘包、拆包?
对于什么是粘包、拆包问题,我想先举两个简单的应用场景:
客户端和服务器建立一个连接,客户端发送一条消息,客户端关闭与服务端的连接。
客户端和服务器简历一个连接,客户端连续发送两条消息,客户端关闭与服务端的连接。
对于第一种情况,服务端的处理流程可以是这样的:当客户端与服务端的连接建立成功之后,服务端不断读取客户端发送过来的数据,当客户端与服务端连接断开之后,服务端知道已经读完了一条消息,然后进行解码和后续处理...。对于第二种情况,如果按照上面相同的处理逻辑来处理,那就有问题了,我们来看看第二种情况下客户端发送的两条消息递交到服务端有可能出现的情况:
第一种情况:
服务端一共读到两个数据包,第一个包包含客户端发出的第一条消息的完整信息,第二个包包含客户端发出的第二条消息,那这种情况比较好处理,服务器只需要简单的从网络缓冲区去读就好了,第一次读到第一条消息的完整信息,消费完再从网络缓冲区将第二条完整消息读出来消费。
没有发生粘包、拆包示意图
第二种情况:
服务端一共就读到一个数据包,这个数据包包含客户端发出的两条消息的完整信息,这个时候基于之前逻辑实现的服务端就蒙了,因为服务端不知道第一条消息从哪儿结束和第二条消息从哪儿开始,这种情况其实是发生了TCP粘包。
TCP粘包示意图
第三种情况:
服务端一共收到了两个数据包,第一个数据包只包含了第一条消息的一部分,第一条消息的后半部分和第二条消息都在第二个数据包中,或者是第一个数据包包含了第一条消息的完整信息和第二条消息的一部分信息,第二个数据包包含了第二条消息的剩下部分,这种情况其实是发送了TCP拆,因为发生了一条消息被拆分在两个包里面发送了,同样上面的服务器逻辑对于这种情况是不好处理的。
TCP拆包示意图
为什么会发生TCP粘包、拆包呢?
发生TCP粘包、拆包主要是由于下面一些原因:
应用程序写入的数据大于套接字缓冲区大小,这将会发生拆包。
应用程序写入数据小于套接字缓冲区大小,网卡将应用多次写入的数据发送到网络上,这将会发生粘包。
进行MSS(最大报文长度)大小的TCP分段,当TCP报文长度-TCP头部长度>MSS的时候将发生拆包。
接收方法不及时读取套接字缓冲区数据,这将发生粘包。
……
如何处理粘包、拆包问题?
知道了粘包、拆包问题及根源,那么如何处理粘包、拆包问题呢?TCP本身是面向流的,作为网络服务器,如何从这源源不断涌来的数据流中拆分出或者合并出有意义的信息呢?通常会有以下一些常用的方法:
使用带消息头的协议、消息头存储消息开始标识及消息长度信息,服务端获取消息头的时候解析出消息长度,然后向后读取该长度的内容。
设置定长消息,服务端每次读取既定长度的内容作为一条完整消息。
设置消息边界,服务端从网络流中按消息编辑分离出消息内容。
……
原文链接:https://my.oschina.net/andylucc/blog/625315
- TCP粘包拆包问题
- Netty系列-TCP粘包拆包问题
- Netty之TCP粘包拆包问题
- Netty中TCP粘包拆包问题
- Netty之TCP粘包拆包问题
- tcp问题
- netty开发之tcp粘包拆包问题
- Netty精粹之TCP粘包拆包问题
- Netty精粹之TCP粘包拆包问题
- Netty精粹之TCP粘包拆包问题
- 基于Netty解决TCP的粘包拆包问题
- TCP中的CRC问题
- TCP粘包问题
- Java TCP 文件传输问题
- TCP连接问题
- TCP粘包问题
- tcp/udp 问题整理
- tcp死连接问题
- java中获取文件或文件夹的路径方法
- CentOS 6.5 升级内核的教程
- 安卓设计模式_单例模式
- quartz的schedule定时调度
- Python单元测试——深入理解unittest
- TCP粘包拆包问题
- 虚拟演播室系统
- java安装1.8的经验和Error: Registry key 'Software\JavaSoft\Java Runtime Environment'\CurrentVers问题处理
- java实现ping的效果
- 文件权限管理__4__特殊权限
- 前端视频网站
- android Fragment与Activity之间数据交互
- git origin 和master的含
- H5图片切换,js图片轮播,js图片自动切换