异步SOCKET接收粘包问题-100分

chinagns 2009-04-02 05:56:48
基于TCP异步SOCKET服务端与客户端程序:

服务端循环分包发送每次包大小为 4906 字节

客户端异步BEGINRECEIVE接收

const int BagSize = 8192

private void receiveCallBack(IAsyncResult ar)
{
Socket MySocket = (Socket)ar.AsyncState;

int receLen = 0;
try
{
//** 此处每次接收的字节应该是分包发送的字节(4096),但是除第一次接收为4096外(10%为8192),接收其他分包都为8192
receLen = MySocket.EndReceive(ar);
}

catch (Exception err)
{
return;
}

if (receLen > 0)
{

byte[] currentBin = new byte[receLen];
Buffer.BlockCopy(data, 0, currentBin, 0, receLen);
MyList.ReceivedCallBack(currentBin, MySocket, ar); //此处逻辑处理收到数据

try
{
ReceiveData();
}
catch (SocketException)
{
MySocket.Close();
}

}

else
{

}

}

例如服务端发送10K的字节,那么是分为三个包发送的,第一个4906字节,第二个4906字节,第三个428字节,每次循环分包发送均不延时。

问:

客户端在接收的时候,怎么解决粘包的问题。
...全文
1283 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
nullnullcao 2012-08-17
  • 打赏
  • 举报
回复
请问楼主。。你的客户端是怎么解决这个问题的?
chinagns 2009-04-03
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 Linux7985 的回复:]
你管他粘不粘包,你只管,你要收到的数据,收完了没有

你可以在最后的地方设置一个标识,当10K读完的时候,最后读到那个标识 ,你就知道你要的数据已经读取完成了,反正方法很多,你不要底层是不是粘包了,或是延迟了,反正你没有读到这个标志,你就一直读,因为TCP他会保证,先送的包,一定会先达到(换个说话,也就是你发送的顺序和你接收的顺序是肯定是一致的,而且不会丢包,因为丢包,服务端肯定会自己重发,以保证绝不…
[/Quote]


呵呵 请你看清楚我的问题。我是分包循环发送,每个包都经过序列化有自己的索引。我的问题不是丢包,是粘包。数据接收是写入缓冲区的。数据接收到以后要反序列化重新组合。请把粘包的概念搞清楚在回复。谢谢
chinagns 2009-04-03
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 Linux7985 的回复:]
你管他粘不粘包,你只管,你要收到的数据,收完了没有

你可以在最后的地方设置一个标识,当10K读完的时候,最后读到那个标识 ,你就知道你要的数据已经读取完成了,反正方法很多,你不要底层是不是粘包了,或是延迟了,反正你没有读到这个标志,你就一直读,因为TCP他会保证,先送的包,一定会先达到(换个说话,也就是你发送的顺序和你接收的顺序是肯定是一致的,而且不会丢包,因为丢包,服务端肯定会自己重发,以保证绝不…
[/Quote]


呵呵 请你看清楚我的问题。我是分包循环发送,每个包都经过序列化有自己的索引。我的问题不是丢包,是粘包。数据接收是写入缓冲区的。数据接收到以后要反序列化重新组合。请把粘包的概念搞清楚在回复。谢谢
chinagns 2009-04-03
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wuyq11 的回复:]
http://www.cnblogs.com/wzd24/archive/2007/12/24/1011932.html
[/Quote]

应用ANALYER类,读取输出中,READINT异常,COUNT值为-16777210
lisot 2009-04-03
  • 打赏
  • 举报
回复
如果对效率要求不高的话,可以考虑发送端先发包的长度,再发包的内容;接受时按照确定的长度,接受包的内容,只是每次需要额外传送4字节的长度信息
zzxap 2009-04-03
  • 打赏
  • 举报
回复
http://download.csdn.net/down/335689/tsky0722
烈火蜓蜻 2009-04-03
  • 打赏
  • 举报
回复
你管他粘不粘包,你只管,你要收到的数据,收完了没有

你可以在最后的地方设置一个标识,当10K读完的时候,最后读到那个标识 ,你就知道你要的数据已经读取完成了,反正方法很多,你不要底层是不是粘包了,或是延迟了,反正你没有读到这个标志,你就一直读,因为TCP他会保证,先送的包,一定会先达到(换个说话,也就是你发送的顺序和你接收的顺序是肯定是一致的,而且不会丢包,因为丢包,服务端肯定会自己重发,以保证绝不丢失一个包)
wts_net 2009-04-03
  • 打赏
  • 举报
回复
学习
chinagns 2009-04-03
  • 打赏
  • 举报
回复
搞定,感谢 Linux7985 和 soaringbird
homejiji 2009-04-03
  • 打赏
  • 举报
回复
把多余出来的先保存起来,等下次接收的时候再用不就可以了。。。这还只是多,还有少的时候呢。。。在接包的时候写一段组包的代码,例如你每次发1000,那接受的时候当组合之后的结果小于1000不处理,将数据保存,再等待接受,如果等于1000代表接收成功往下处理,如果大于1000,取出1000,多余部分保存,往下处理
soaringbird 2009-04-03
  • 打赏
  • 举报
回复
粘包也算是个问题?
楼主请看清linux7985的答复,一点都没错。
理论上讲,tcp保证了数据包不会丢,不会乱。tcp的优化算法也会造成所谓的粘包(把你的小包(如果也叫包)放到一个大的tcp包里)。你只要把接收到的数据按顺序放到一个缓冲区里,再按照你的数据的定义,定长的也好,有结构的也好,按照你的定义去处理就好了,不符合定义的就说明没接收完,继续接收。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧