小编给大家分享一下c#中关于TCP粘包出现的问题如何解决,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!
<强>一、TCP粘包产生的原理强>
1. TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。出现粘包现象的原因是多方面的,它既可能由发送方造成,也可能由接收方造成。
2。发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象。
3。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据,
<强>二,解决原理及代码实现强>
1。采用包头(固定长度,里面存着包体的长度,发送时动态获取)+包体的传输机制。如图
HeaderSize存放着包体的长度,其HeaderSize本身是定长4字节;
一个完整的数据包(L)=HeaderSize + BodySize;
2。分包算法
其基本思路是首先将待处理的接收数据流即系统缓冲区数据(长度设为M)强行转换成预定的结构数据形式,并从中取出结构数据长度字段L,而后根据包头计算得到第一包数据长度。
1)若L 2)若L=M,则表明数据流内容恰好是一完整结构数据(即用户自定义缓冲区等于系统接收缓冲区大小),直接将其存入临时缓冲区即可。 3)若L> M,则表明数据流内容尚不够构成一完整结构数据,需留待与下一包数据合并后再行处理。 4)下面是代码代码实现(HP-SOCKET框架的服务器端来接收数据) int headSize=4;//包头长度固定4
byte [] surplusBuffer=零;//不完整的数据包,即用户自定义缓冲区///& lt; summary>///接收客户端发来的数据///& lt;/summary>///& lt;参数name=癱onnId"在每个客户的会话ID///& lt;参数name=癰ytes"在缓冲区数据& lt;/param>///& lt; returns> & lt;/returns>
私人HandleResult>私人HandleResult>//线程安全的字典
ConcurrentDictionary