{mtitle}这两天在学习socket收发消息的问题,学到了新知识{/mtitle}
1、对于一次接收到大于接收缓存的消息,并且连续接收消息,两段消息可能同时被接受到一端缓存中,叫粘包;
2、收到的消息不足一个接收缓存,交半包;
程序的几个注意点:
1、必须要循环接收消息;
2、消息头必须要有长度标志字节(这里是用的前四个字节来保存实际消息体的长度);
3、除了接收缓存rev之外还需要一个cache缓存byte[] ,用来保存一条完整的消息;
4、cache缓存可能不足一个接收缓存,那后面不足的会有0 补充 ,半包;
5、cache缓存 可能刚好一个接收缓存,并且包含>= 1个完整消息(等于的时候无粘包,大于的时候有粘包);
6、cache缓存 大于一个接收缓存,这里需要循环接收(用长度标志字节来判断),直到接收到 >= 一个完整消息,还是5、的情况;
7、接受完一个完整消息后,需要清空缓存,或者将有粘包的字节重新拷贝到cache缓存;
Socket soc = obj as Socket;
int recvlen = 0;
byte[] cacheBuf = null;
byte[] recvBuf = new byte[100];
if (soc != null)
{
while ((recvlen = soc.Receive(recvBuf)) > 0)
{
if (cacheBuf == null)
{
cacheBuf = new byte[recvlen];
Array.Copy(recvBuf, cacheBuf, recvlen);
}
else
{
byte[] t = new byte[cacheBuf.Length + recvlen];
Array.Copy(cacheBuf, t, cacheBuf.Length);
Array.Copy(recvBuf, 0, t, cacheBuf.Length, recvlen);
cacheBuf = t;
}
if (cacheBuf.Length <= 4)
continue;
int msgl = BitConverter.ToInt32(cacheBuf, 0);
while (cacheBuf!=null && msgl + 4 <= cacheBuf.Length)
{
byte[] msgbyte = new byte[msgl];
Array.Copy(cacheBuf, 4, msgbyte, 0, msgl);
test(msgbyte,soc);//拿到完整消息,具体消息操作
if (msgl + 4 == cacheBuf.Length)
{
cacheBuf = null;
}
else
{
byte[] tmpByte = new byte[cacheBuf.Length - msgl - 4];
Array.Copy(cacheBuf, msgl + 4, tmpByte, 0, cacheBuf.Length - msgl - 4);
cacheBuf = tmpByte;
}
}
}
}
文章很有不错
学习了