CSocket的OnReceive如何实现接收完整的数据?

蜗牛先生慢慢走 2012-01-16 11:01:38
客户端的socket类继承了CSocket,在OnReceive中接收服务器发来的数据,服务器每次发过来数据的大小为6k左右,在局域网内测试的时候没什么问题,把服务器程序搭在外网测试,6k的数据大多数会被分成两次来发送,有时多有时少,这样的话,每次都不能收到完整的数据,应该怎么解决?
...全文
420 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
gameslq 2012-01-21
  • 打赏
  • 举报
回复
tcp/ip层只能保证报文或帧的完整性,而要处理业务数据的话,就需要自己设计好协议数据格式
通用做法 包头+业务数据,而包头中需要包括数整个协议的长度,才能保证业务数据的完整性,收到数据后
根据协议中的长度,循环接收,直到收完为止。
tomtzh 2012-01-21
  • 打赏
  • 举报
回复
同意5楼,我一般是这样做的,当然,有必要的话还要加校验。
Eleven 2012-01-19
  • 打赏
  • 举报
回复
自定义协议,包头+数据,包头含有数据长度信息
zhanshen2891 2012-01-16
  • 打赏
  • 举报
回复
使用TCP的话就是会有这种情况的,你需要自己处理一下。就是自己定义出消息边界,收到消息的时候划分成数据包再交给上层逻辑。

比如可以在发包的时候加上2个字节长度的内容,里面存上接下来的数据的长度。
lizexi_1 2012-01-16
  • 打赏
  • 举报
回复
补充一下,首先要通过包头来判断是否已经收到一个完整的包了,没有收到,那就再循环等待,等到,所有的包收齐为止,再处理这个包,并丢弃这个包。
lizexi_1 2012-01-16
  • 打赏
  • 举报
回复
BOOL SSocket::OnReceive(int nError)
{

if( TSOCKET_SUCCESS != nError ) return FALSE;

//-----------------------------------------------------------------
// 数据包头还未满
//-----------------------------------------------------------------
if (m_nRecvBufLen<sizeof(QHEADER)) return FALSE;

PQHEADER pHeader=(PQHEADER)m_pRecvBuf;
int nMsgLen = HEADER_LENGTH + pHeader->dwLength;
//-----------------------------------------------------------------
// 完整的数据包还未到达
//-----------------------------------------------------------------
if ( m_nRecvBufLen < nMsgLen ) return FALSE;

void *pTmp = malloc(nMsgLen);
memcpy(pTmp, m_pRecvBuf, nMsgLen);
TSOCKET_EVENT *event = new TSOCKET_EVENT;
event->eventType = TEVENT_RECEIVE;
event->errCode = nError;
event->pSocket = this;
event->pMsg = pTmp;

// 看看是否是加密包,如果是加密包,那么还要解密
if( SID_ENCRYPT == ( QID_ENCRYPT & pHeader->dwType ) )
{ // 加密的消息
m_pManager->RC5_DecryptMessage( pTmp ) ; // 解密
}

EnterCriticalSection(&m_pManager->m_cs);
m_pManager->m_queueMsgs.AddTail(event);
LeaveCriticalSection(&m_pManager->m_cs);
//OnMsg(pHeader);

//-----------------------------------------------------------------
// 剩下的是下一个要处理数据包的数据
//-----------------------------------------------------------------
m_nRecvBufLen -= nMsgLen;
memmove( m_pRecvBuf, m_pRecvBuf + nMsgLen, m_nRecvBufLen);

return TRUE;
}
quwei197874 2012-01-16
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zhanshen2891 的回复:]
使用TCP的话就是会有这种情况的,你需要自己处理一下。就是自己定义出消息边界,收到消息的时候划分成数据包再交给上层逻辑。

比如可以在发包的时候加上2个字节长度的内容,里面存上接下来的数据的长度。
[/Quote]++

18,356

社区成员

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

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