Socket.EndReceive 为什么只返回字节数,BeginReceive 设置的buffer 确没接收到任何数据?

无用兄 2010-04-03 11:34:09
客户端我使用 Socket.BeginReceive 开始一个接收请求:
m_ClientSocket.BeginReceive(m_RecvBuffer, 0, 2048 0, new AsyncCallback(ReadCallBack), this);


private void ReadCallBack(IAsyncResult ar)
{
try
{
m_RecvSize = m_ClientSocket.EndReceive(ar);
....

因为要从服务端向客户端分包发送一个文件所以发送的频率非常高,在第一次ReadCallBack 调用EndReceive执行后 返回正确数据大小 m_RecvBuffer 里面的数据是正确的,可是当第二以后ReadCallBack 调用EndReceive执行后 返回的数据大小虽然正确,但是m_RecvBuffer 数据就不正确了,全部是0. 调试了很多次都这样,请问是什么原因?谢谢了.
...全文
476 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
[Quote=引用楼主 chzhe 的回复:]
因为要从服务端向客户端分包发送一个文件所以发送的频率非常高,在第一次ReadCallBack 调用EndReceive执行后 返回正确数据大小 m_RecvBuffer 里面的数据是正确的,可是当第二以后ReadCallBack 调用EndReceive执行后 返回的数据大小虽然正确,但是m_RecvBuffer 数据就不正确了,全部是0. 调试了很多次都这样[/Quote]看不懂。

假设服务器返回的包有3000个字节,那么第一次调用ReadCallBack 会接收到2048个字节,第二次调用会接收到952个字节。如果服务器发送下一个数据包稍微快一点,那么可能不止952个字节,而是粘包有第二个包的一些内容。

这很正常啊。你到底要什么结局呢?
qiuqingpo 2010-04-03
  • 打赏
  • 举报
回复
可能是这样的吧:
由于系统缓冲区空间不足或列队已满,不能执行套接字上的操作
我也遇到了这样的问题了我的提问页面:
http://topic.csdn.net/u/20100403/10/2e2fa5cf-18dd-4965-98b8-353103db4208.html?seed=174694824&r=64405152#r_64405152
大家一起就这两个问题一起交流一下。
无用兄 2010-04-03
  • 打赏
  • 举报
回复
谢谢大家,已经解决了,方法:
1.

m_RecvSize += m_ClientSocket.EndReceive(ar); //m_RecvSize是类成员,这个地方需要累加.

//数据包头大小
int nHeadSize = Marshal.SizeOf(typeof(tagCMDHead));

while (m_RecvSize >= nHeadSize)
{
//转为结构体
tagCMDHead cmdHead = (tagCMDHead)DataOperate.ByteToObject (m_RecvBuffer, typeof(tagCMDHead));
//数据包大小
int nPackSize = nHeadSize + cmdHead.wDataSize;

if (m_RecvSize < nPackSize) break;

//接收用户数据
byte[] byteData = DataOperate.MidByte(m_RecvBuffer, nHeadSize, nPackSize);
m_SocketEvent.OnRecv(cmdHead.wMainFlag, cmdHead.wSubFlag,
byteData, cmdHead.wDataSize);

//继续接收
byte[] nPartBuffer = DataOperate.MidByte(m_RecvBuffer, nPackSize, m_RecvSize);

//复制数据
DataOperate.ArrayCopy(m_RecvBuffer, 0, nPartBuffer, 0, nPartBuffer.Length);
m_RecvSize -= nPackSize;
}
}

投递接收请求时:
m_ClientSocket.BeginReceive(m_RecvBuffer, m_RecvSize, SOCKET_RECV_BUFFER_SIZE - m_RecvSize, 0, new AsyncCallback(ReadCallBack), this);
这样就可以了.

qiuqingpo 2010-04-03
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sp1234 的回复:]

引用 1 楼 qiuqingpo 的回复:
可能是这样的吧:
由于系统缓冲区空间不足或列队已满,不能执行套接字上的操作
我也遇到了这样的问题了我的提问页面:
http://topic.csdn.net/u/20100403/10/2e2fa5cf-18dd-4965-98b8-353103db4208.html?seed=174694824&amp;r=64405152#r_64……
[/Quote]
确实是出现了.可能是什么原因呢.能不能再回答一下.谢谢
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 qiuqingpo 的回复:]
可能是这样的吧:
由于系统缓冲区空间不足或列队已满,不能执行套接字上的操作
我也遇到了这样的问题了我的提问页面:
http://topic.csdn.net/u/20100403/10/2e2fa5cf-18dd-4965-98b8-353103db4208.html?seed=174694824&r=64405152#r_64405152
大家一起就这两个问题一起交流一下。
[/Quote]

这个问题在真正的异步发送中是不出现的。

110,566

社区成员

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

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

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