求助!CAsyncSocket的OnReceive()刚建立连接时正常,运行一段时间后不再触发! 30
客户端定时向服务端发送数据包,数据格式是我自定的,前面四个字节保存数据包的大小(包头),后面的空间存储数据(包体)。我之前设计的只是发送固定长度的数据包,程序运行一天都是...
客户端定时向服务端发送数据包,数据格式是我自定的,前面四个字节保存数据包的大小(包头),后面的空间存储数据(包体)。
我之前设计的只是发送固定长度的数据包,程序运行一天都是正常的,后来为节省网络资源,所以改成为发送自定义数据包的形式。刚建立连接时,程序运行正常。可是过一段时间后(可能是几秒,运气好的话,可以正常接收十多分钟),客户端Send并没有异常,但OnReceive不再触发了。
是不是传说中的“粘包”问题?可是我的接收处理过程不可能没有读完缓存区啊,求高手指点!或者提供CAsyncSocket自定义数据包形式(包头&包体)发送接收的代码也行,万分感激!
邮箱:vhei00@163.com
客户端发送数据包代码(定时器的时间我设的是1秒):
CString temp = "测试数据";
char *datainfo = temp.GetBuffer(0);
int datalength = strlen(datainfo)+1;
char* m_msg = NULL;
int iLen = datalength +4; //数据包的长度
m_msg = new char[iLen]; //分配地址空间
memset(m_msg, 0, iLen);
memcpy(m_msg,&iLen, 4); //前4个字节载入数据包的长度信息(包头)
memcpy(m_msg+4,datainfo, iLen-4); //将数据载入m_msg的剩余空间(包体)
m_clientSocket.Send(m_msg,iLen); //发送消息
delete[] m_msg;
服务端OnReceive()中的处理代码:
int iRet;
int iReadLen = 0;
char Length[4]; //缓存接收数据的前四个字节的数据包的长度信息
char* pBuf = NULL; //接收数据的缓存区
//接收数据的前四个字节的数据包的长度信息,即读包头信息/////////////////////////
while( iReadLen < 4)
{
iRet = pClientSocket->Receive( Length + iReadLen , 4 - iReadLen );
if( iRet == 0 )
{
return;
}
if( iRet == SOCKET_ERROR )
{
return;
}
iReadLen += iRet;
}
//将包长度数据还原成iLen
int iLen;
memcpy(&iLen, Length, 4);
TRACE("#############包长度:%d ################## ",iLen);
//按接受包长度创建buf长度
pBuf = new char[iLen];
memcpy(pBuf,Length,4); //将数据包的长度信息放入pBuf的前四个字节
//包体部分接收
while( iReadLen < iLen)
{
iRet = pClientSocket->Receive( pBuf + iReadLen , iLen - iReadLen);
if( iRet == 0 )
{
delete[] pBuf;
return;
}
if( iRet == SOCKET_ERROR )
{
iRet = GetLastError();
delete[] pBuf;
return;
}
iReadLen += iRet;
}
TRACE("############# 接收完成 ##################\n ");
delete[] pBuf; 展开
我之前设计的只是发送固定长度的数据包,程序运行一天都是正常的,后来为节省网络资源,所以改成为发送自定义数据包的形式。刚建立连接时,程序运行正常。可是过一段时间后(可能是几秒,运气好的话,可以正常接收十多分钟),客户端Send并没有异常,但OnReceive不再触发了。
是不是传说中的“粘包”问题?可是我的接收处理过程不可能没有读完缓存区啊,求高手指点!或者提供CAsyncSocket自定义数据包形式(包头&包体)发送接收的代码也行,万分感激!
邮箱:vhei00@163.com
客户端发送数据包代码(定时器的时间我设的是1秒):
CString temp = "测试数据";
char *datainfo = temp.GetBuffer(0);
int datalength = strlen(datainfo)+1;
char* m_msg = NULL;
int iLen = datalength +4; //数据包的长度
m_msg = new char[iLen]; //分配地址空间
memset(m_msg, 0, iLen);
memcpy(m_msg,&iLen, 4); //前4个字节载入数据包的长度信息(包头)
memcpy(m_msg+4,datainfo, iLen-4); //将数据载入m_msg的剩余空间(包体)
m_clientSocket.Send(m_msg,iLen); //发送消息
delete[] m_msg;
服务端OnReceive()中的处理代码:
int iRet;
int iReadLen = 0;
char Length[4]; //缓存接收数据的前四个字节的数据包的长度信息
char* pBuf = NULL; //接收数据的缓存区
//接收数据的前四个字节的数据包的长度信息,即读包头信息/////////////////////////
while( iReadLen < 4)
{
iRet = pClientSocket->Receive( Length + iReadLen , 4 - iReadLen );
if( iRet == 0 )
{
return;
}
if( iRet == SOCKET_ERROR )
{
return;
}
iReadLen += iRet;
}
//将包长度数据还原成iLen
int iLen;
memcpy(&iLen, Length, 4);
TRACE("#############包长度:%d ################## ",iLen);
//按接受包长度创建buf长度
pBuf = new char[iLen];
memcpy(pBuf,Length,4); //将数据包的长度信息放入pBuf的前四个字节
//包体部分接收
while( iReadLen < iLen)
{
iRet = pClientSocket->Receive( pBuf + iReadLen , iLen - iReadLen);
if( iRet == 0 )
{
delete[] pBuf;
return;
}
if( iRet == SOCKET_ERROR )
{
iRet = GetLastError();
delete[] pBuf;
return;
}
iReadLen += iRet;
}
TRACE("############# 接收完成 ##################\n ");
delete[] pBuf; 展开
3个回答
展开全部
说说你接收程序问题。
我想既然你都是异步处理的,
你这边应该有多长就收多长,总不能数据没有来还一直都在读罢?
因此你用while一直强行读取的方法有可能犯忌,也有可能导致socket状态异常,出现你说的问题。
另外既然有数据,你总应该读完吧,否则socket怎么知道应不应该再次调用你的onreceive呢?
所以建议你一次把所有数据读入,然后再自行处理长度不够和太长问题。
while( iReadLen < 4)
{
iRet = pClientSocket->Receive( Length + iReadLen , 4 - iReadLen );
我想既然你都是异步处理的,
你这边应该有多长就收多长,总不能数据没有来还一直都在读罢?
因此你用while一直强行读取的方法有可能犯忌,也有可能导致socket状态异常,出现你说的问题。
另外既然有数据,你总应该读完吧,否则socket怎么知道应不应该再次调用你的onreceive呢?
所以建议你一次把所有数据读入,然后再自行处理长度不够和太长问题。
while( iReadLen < 4)
{
iRet = pClientSocket->Receive( Length + iReadLen , 4 - iReadLen );
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
我加了一句AsyncSelect(FD_READ)问题貌似解决了。
我对CAsyncSocket了解不深,这个接收代码的逻辑是在网上学的,好像他认为服务端接收时会将客户端即使是分批发送的一个包在接收队列中排好。不知道这个逻辑对不对....
我对CAsyncSocket了解不深,这个接收代码的逻辑是在网上学的,好像他认为服务端接收时会将客户端即使是分批发送的一个包在接收队列中排好。不知道这个逻辑对不对....
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
重载CAsyncSocket::OnReceive
添加代码
char buf[10];
int len=receive(buf,10);
if(len>0)
{
//你想扎存那就存那
}
添加代码
char buf[10];
int len=receive(buf,10);
if(len>0)
{
//你想扎存那就存那
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询