现象描述
由于TCP协议本身的机制
客户端与服务器会维持一个连接发送数据
粘包原因
如果发送的网络数据包太小,TCP则会合并较小的数据包再发送,
接收端便无法区分哪些数据是发送端自己分开的,
因此便会产生粘包现象。
或者,接收端把数据放到接收缓冲区中,
如果数据没有及时从缓冲区取走,
下次取数据时就可能出现一次取走多个数据包的情况。
如:
客户端Send:hello
客户端Send:unity
服务端Recv:Recv
分包原因
如果发送的数据包太大,TCP有可能会将它拆分成多个包发送
接收端的一次Receive可能只收到一部分数据。
如:
客户端Send:hellounity
服务端Recv:hel
服务端Recv:lounity
处理办法
每个数据包前加上长度字节
如果缓冲区的数据长度大于要提取的字节数
则取出相应的字节
否则等待下一次数据接收
代码实现
private void ProcessData(Conn conn) {
//小于字节长度
if (conn.buffCount < sezeof(Int32))
return;
//消息长度
Array.Copy(conn.readBuff,conn.lenBytes,sizeof(Int32));
conn.msgLength = BitConverter.ToInt32(conn.lenBytes,0);
if(conn.buffCount < conn.msgLength + sizeof(Int32))
return;
//处理消息
string str = System.Text.Encoding.UTF8.GetString(conn.readBuff,sizeof(Int32),conn.msgLength);
Console.WriteLine("收到消息["+conn.GetAdress() + "]" + str);
Send(conn,str);
//清除已处理的消息
int count = conn.buffCount - conn.msgLength = sizeof(Int32);
Array.Copy(conn.readBuff,sizeof(Int32) + conn.msgLength,conn.readBuff,0,count);
conn.buffCount = count;
if(conn.buffCount > 0){
ProcessData(conn);
}
}
当然,这段代码是无法直接复制粘贴使用的
因为里面涉及到了很多其他的API
在这里只需要了解实现的方式即可
来源:https://www.cnblogs.com/fws94/p/7127552.html