套接字异步模式CAsyncSocket::OnReceive不再触发,什么原因?

haogeai123 2011-05-21 11:10:07
系统采用C/S模式。服务器向客户端发送大量数据(文件大小几M到几G不等)。服务器和客户端都的套接字都是从CAsyncSocket派生,连接采用TCP模式。
数据传送流程:(一“问”一“答”)
1.服务器每次向客户端发送4096个字节数据,然后等待客户端确认。
2.客户端在OnReceive里接收数据。如果接收到4096个字节便向服务器发送确认信息,否则继续等待其余的数据。
3.客户端总是在收到4096个字节后才向服务器发送确认信息。
4.服务器在收到客户端的确认信息后再向客户端发送4096个字节的数据。
5.不断重复,直到数据发送完成。
问题描述:
有时候,服务器向客户端发送了4096个字节。而在客户端接收数据的时候,由于网络或者其他原因,客户端一次无法收到4096个字节的数据。我通过写日志的方法发现:客户端只能两次触发OnReceive函数,然后就不再响应了。
经常的情况是:在日志中的记录是——客户端收到了344个字节,然后又收到了344个字节;之后就没有记录了。也就是说,客户端不再收到数据了。但是,服务器端是发送了4096个字节的数据(通过日志的记录知道)。而客户端却没有收到全部的数据。经过我的分析判断得到的问题是:OnReceive在触发了两次后就不再触发了。
我在本地计算机中用127.0.0.1巡回测试也是这样。服务器确实已经发送了4096个字节。因为不存在网络的问题,客户端应该是可以直接收到4096个字节数据的。但是问题依旧。

我在网上找了许多关于CAsyncSocket的内容都没有发现这个问题的解决办法。
我的猜想:会不会是粘包的问题??如果是又怎么解决。
期待得到的帮助:
1.如何知道CAsyncSocket派生的类有没有及时收到FD_READ的消息,并且进入了相应的OnReceive函数。(无法单步调试和断点调试,因为这种情况不是经常发生,有时候没有问题,有时候在发送了一部分数据后才出错。我用断点调试时,不会发生错误,我已经用过各类断点多次调试过了。只能是通过写日志的方法记录出错的过程。
2.如何知道接收缓冲区中有没有数据??(我想在客户端没有一次收到4096个字节数据时,利用定时检测接收缓冲区是否有数据,然后手动调用Receive函数接收数据。我也知道,在异步模式下,当有数据到来后会自动产生FD_READ,然后调用OnReceive。但是,目前发现的情况是——在两次调用OnReceive后就没有自动调用OnReceive函数了。

这个问题已经困扰了好几天了,希望各位可以尽己所能,鼎力相助。
...全文
416 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
haogeai123 2011-05-22
  • 打赏
  • 举报
回复
谢谢各位了。经过重新分析和测试,问题不在套接字。是其他的问题所致的。
_free 2011-05-21
  • 打赏
  • 举报
回复

void CMyAsyncSocket::OnReceive(int nErrorCode) // CMyAsyncSocket is
// derived from CAsyncSocket
{
static int i=0;

i++;

TCHAR buff[4096];
int nRead;
nRead = Receive(buff, 4096);

switch (nRead)
{
case 0:
Close();
break;
case SOCKET_ERROR:
if (GetLastError() != WSAEWOULDBLOCK)
{
AfxMessageBox ("Error occurred");
Close();
}
break;
default:
buff[nRead] = 0; //terminate the string
CString szTemp(buff);
m_strRecv += szTemp; // m_strRecv is a CString declared
// in CMyAsyncSocket
if (szTemp.CompareNoCase("bye") == 0 ) ShutDown();
}
CAsyncSocket::OnReceive(nErrorCode);
}





nRead = Receive(buff, 4096);
对nRead处理环节上出问题了 ??

Eleven 2011-05-21
  • 打赏
  • 举报
回复
你简单的可以用抓包工具抓个包看看,是发送端的问题还是接收端得问题。看看数据是否都发送出去,接收端数据是否都到达了,先定位问题所在
cnzdgs 2011-05-21
  • 打赏
  • 举报
回复
把OnReceive包含写日志的相关代码贴上来。再贴上最后一段日志的内容。
lijianli9 2011-05-21
  • 打赏
  • 举报
回复
recvice不能保证一次接收完4096个字节,你要循环接收的吧。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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