TCP通讯处理粘包详解
来源:互联网 发布:淘宝联盟浏览器插件 编辑:程序博客网 时间:2024/06/11 12:06
转http://www.cnblogs.com/smark/p/3284756.html
一般所谓的TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据。TCP通讯为何存在粘包呢?主要原因是TCP是以流的方式来处理数据,再加上网络上MTU的往往小于在应用处理的消息数据,所以就会引发一次接收的数据无法满足消息的需要,导致粘包的存在。处理粘包的唯一方法就是制定应用层的数据通讯协议,通过协议来规范现有接收的数据是否满足消息数据的需要。在应用中处理粘包的基础方法主要有两种分别是以4节字描述消息大小或以结束符,实际上也有两者相结合的如HTTP,redis的通讯协议等。
在平时交流过程发现一些朋友即使做了这些协议的处理,但有时在处理数据的时候也会出现数据不对的情况。这主要原因他们在一些个别情况下没有处理好。因为当一系列的消息发送过来的时候,对于4节字头或结束符分布位置都是不确定的。一种简单的情况就是当前消息处理完成后,紧接着就是处理一下个消息的4节字描述,但在实际情况下当前接收的buffer剩下的内容有可能不足4节字的。如果你想通过通讯的程序来测这情况相对来说触发的机率性不高,所以对于协议分析的功能最好通过单元测试来模拟。
通过下面这个图可以更清晰地了解协议标记数据分布的情况
下面简单地介绍一下4字节描述大小和结束符和处理方式。
4字节大小描述方式
复制代码
1 public void Import(byte[] data, int start, int count)
2 {
3 while (count > 0)
4 {
5 if (!mLoading)
6 {
7 mCheckSize.Reset();
8 mStream.SetLength(0);
9 mStream.Position = 0;
10 mLoading = true;
11 }
12 if (mCheckSize.Length == -1)
13 {
14 while (count > 0 && mCheckSize.Length == -1)
15 {
16 mCheckSize.Import(data[start]);
17 start++;
18 count–;
19 }
20 }
21 else
22 {
23 if (OnImport(data, ref start, ref count))
24 {
25 mLoading = false;
26 if (Receive != null)
27 {
28 mStream.Position = 0;
29 Receive(mStream);
30 }
31 }
32 }
33 }
34 }
35
36
37 public void Import(byte value)
38 {
39 LengthData[mIndex] = value;
40 if (mIndex == 3)
41 {
42 Length = BitConverter.ToInt32(LengthData, 0);
43 if (!LittleEndian)
44 Length = Endian.SwapInt32(Length);
45 }
46 else
47 {
48 mIndex++;
49 }
50 }
复制代码
代码很简单如果没有长度描述的情况就把数据导入到消息长度描述的buffer中,如果当前buffer满足4位的情况直接得到相应长度。后面的工作就是获取相应长度的buffer即可。
结束符方式
复制代码
1 public void Import(byte[] data, int start, int count)
2 {
3 while (count > 0)
4 {
5 if (!mLoading)
6 {
7 mStream.SetLength(0);
8 mStream.Position = 0;
9 mLoading = true;
10 }
11 if (data[x] == mEof[0])
12 {
13 start += mEof.Length;
14 count -= mEof.Length;
15 mLoading = false;
16 if (Receive != null)
17 {
18 mStream.Position = 0;
19 Receive(mStream);
20 }
21 }
22 else
23 {
24 mStream.Write(data[start]);
25 start++;
26 count–;
27 }
28 }
29 }
复制代码
结束符的处理方式就相对来说简单多了。
以上就是两种TCP数据处理粘包的情况,相关代码紧供参考。
- TCP通讯处理粘包详解
- TCP粘包处理
- socket TCP 处理粘包
- 处理tcp粘包问题
- tcp 粘包处理 TCP_NODELAY
- golang tcp粘包处理
- tcp 粘包,碎包处理 test
- Socket通讯TCP/UDP粘包,多包和断包、少包问题解读
- Socket编程 (异步通讯,解决Tcp粘包)
- Socket编程 (异步通讯,解决Tcp粘包)
- TCP粘包处理-RingBuf方法
- TCP分包方法 && 粘包处理策略
- 关于tcp粘包的处理
- Win32 TCP粘包处理,源代码。
- TCP分包方法 && 粘包处理策略
- tcp粘包的处理(待完成)
- 结构体传输 & TCP粘包处理
- TCP新手误区--粘包的处理
- Java原始数据类型
- oracle里用管理员权限把A用户的表授权给B用户去使用
- 【数据结构与算法】选择排序
- 字符设备驱动---Led
- Bzoj 2818: Gcd(莫比乌斯反演)
- TCP通讯处理粘包详解
- java中Double类型的科学计数法
- sscanf
- Java int数据类型
- 【数据结构与算法】冒泡排序
- 通过docker 里面的Image 输出hello world
- 浅谈Web网站架构演变过程(转)
- 动态显示时间
- sql