CSocket::OnReceive()的问题

赤勇玄心行天道 2009-02-18 05:02:02
我对CSocket类做了一个实验,在相应OnReceive()的函数时,用了两种不同的方法,但是意思是一样的,却出现了完全不同的效果,用TCP协议。

void CMySocket::OnReceive(int nErrorCode)//1
{
char j[100];
Receive(j,sizeof(j)/2);
Receive(j,sizeof(j)/2);
Send(j,sizeof(j));
}

void CMySocket::OnReceive(int nErrorCode)//2
{
char j[100];
Receive(j,sizeof(j));
Send(j,sizeof(j));
}

先创建一个Socket监听,再用创建一个Socket连接,连接的后马上发送一次数据。

大家看得出,这样子会让程序处于一个死循环的状态,可是实际上第一种方法,在循环不确定次数后,会断掉,第二种方法才可以无休止的循环下去。

这个情况是我在编程的一个需要时发现的,我需要接受一个数据包的前一部分,再根据前一个部分再来接收后一部分,再发送相关数据给对方,然后就出现了以上问题,我是在一台机器上用“127.0.0.1”的地址试的,希望大家能仔细的帮帮我。
...全文
191 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
我的程序是这样的,一个数据包的分成两个部分,前一部分标志有整个数据包的大小和目的,然后接收数据时,先接收前一部分,再根据前一部分来接收后一部分,这样就保证了完整性,然后就出现了以上问题,所以特别难解决。看看大家是不是有什么更好的方法教教我?
百事烟 2009-02-21
  • 打赏
  • 举报
回复
每次收到的字节数不是固定的,是不可预计的,如果第1个recv把缓冲区里的数据接收完毕,第二个recv会出现返回0的状况,自己判断好了应该也没大事,不过最好不要这样用,我也没实践过...
  • 打赏
  • 举报
回复
非常感谢Delphigis的精彩回答,同时也感谢所有支持我的人,我的难题终于解开了。
百事烟 2009-02-21
  • 打赏
  • 举报
回复
大部分TCP传输都会采用数据头和数据分离的方式,
网上TCP的例子都有这部分的,大概过程是这样的
设置1个公共变量,保存数据头是否已接收成功 //BOOL bHead;
if (!bHead) //接收数据头
{
if(数据头的节数没有接收完)
{
//接收数据头 iCount = recv(...); //累加iCount
}
if(数据头字节数接收OK)
{
//判断数据头是否正确
//分析数据头,取出数据本身大小
//bHead = True;//开始接收数据了
}
}
else //接收数据
{
if(数据的节数没有接收完) //数据大小由数据头分析得来
{
//接收数据 iCount = recv(...); //累加iCount
}
if(数据字节数接收OK)
{
//数据处理部分
//bHead = False;//开始接收数据头了
}
}
jy514263 2009-02-20
  • 打赏
  • 举报
回复
CSocket 是AsyncSelect模型的。

如果数据包没有同步接收, 有可能两个包就会一块过来了,变成一块大的包包
  • 打赏
  • 举报
回复
那请问下,为什么只能调用一次recv()这个问题我一直没有搞懂?
baosanr 2009-02-20
  • 打赏
  • 举报
回复
我觉得也应该是阻塞所致,看看你的Recv是不是在单独的线程里.这样即使阻塞程序依然可以响应
百事烟 2009-02-20
  • 打赏
  • 举报
回复
通常OnReceive(int nErrorCode) 中只能调用一次Recv(......);
因为如果没有完全Receive本次发来的数据,会再次触发OnReceive(int nErrorCode)
在Winsocket这是样的,对CSocket不太了解

必须这样写:
int iCount;
iCount = recv(......);
以下代码根据iCount来写

网络开发最好用winsock, CSocket用好了很方便,用不好很麻烦

  • 打赏
  • 举报
回复
为什么没有人愿意帮助我?
caitian6 2009-02-19
  • 打赏
  • 举报
回复
会断掉? 是阻塞在那里了吧。
你的套接字是阻塞的吧, 你分两次来接收, 有可能数据没有接收完整, 所以Receive(j,sizeof(j)/2); 会阻塞在那
  • 打赏
  • 举报
回复
能否解释一下,为什么会断掉,理论上来说,我的接收方式是一样,第二种才能死循环下去,第一种会断掉,这是为什么?
caitian6 2009-02-19
  • 打赏
  • 举报
回复
char j[100];
你自己定义的啊。。。。。。
  • 打赏
  • 举报
回复
请问那个 j + nIdx 是什么意思?
caitian6 2009-02-19
  • 打赏
  • 举报
回复
int nLeft = 100;
int nIdx = 0;
int nRet = 0;
while( nLeft >0 )
{
nRet = recv(j + nIdx , nLeft);
if ( nRet == SOCKET_ERROR)
{
closesocket();
return ;
}
nLeft -= nRet;
nIdx += nRet;
}
  • 打赏
  • 举报
回复
void OnReceive(int nErrorCode)
{
UINT k;
char j[100];
do
{
k=recv(this->m_hSocket,j,sizeof(j)/2,0);
}while(k!=SOCKET_ERROR);
Send(j,sizeof(j));
}

我用这种方法都会断掉。
  • 打赏
  • 举报
回复
不是,我可以肯定的告诉你,是断掉,不是阻塞,两个程序均在活动,我还可以让两个程序再次新建套接字进行连接,发包。

18,356

社区成员

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

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