关于网友提出的“ CSocket的OnReceive如何实现接收完整的数据?”问题疑问,本网通过在网上对“ CSocket的OnReceive如何实现接收完整的数据?”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:
问题: CSocket的OnReceive如何实现接收完整的数据?
描述:本帖最后由 VisualEleven 于 2012-01-19 17:23:11 编辑
客户端的socket类继承了CSocket,在OnReceive中接收服务器发来的数据,服务器每次发过来数据的大小为6k左右,在局域网内测试的时候没什么问题,把服务器程序搭在外网测试,6k的数据大多数会被分成两次来发送,有时多有时少,这样的话,每次都不能收到完整的数据,应该怎么解决?
解决方案1: 同意5楼,我一般是这样做的,当然,有必要的话还要加校验。
解决方案2: 补充一下,首先要通过包头来判断是否已经收到一个完整的包了,没有收到,那就再循环等待,等到,所有的包收齐为止,再处理这个包,并丢弃这个包。
解决方案3:本帖最后由 VisualEleven 于 2012-01-19 17:20:46 编辑
BOOL SSocket::OnReceive(int nError)
{
if( TSOCKET_SUCCESS != nError ) return FALSE;
//-----------------------------------------------------------------
// 数据包头还未满
//-----------------------------------------------------------------
if (m_nRecvBufLen<>
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;
}
解决方案4:++
解决方案5: tcp/ip层只能保证报文或帧的完整性,而要处理业务数据的话,就需要自己设计好协议数据格式
通用做法 包头+业务数据,而包头中需要包括数整个协议的长度,才能保证业务数据的完整性,收到数据后
根据协议中的长度,循环接收,直到收完为止。
解决方案6: 自定义协议,包头+数据,包头含有数据长度信息
解决方案7: 使用TCP的话就是会有这种情况的,你需要自己处理一下。就是自己定义出消息边界,收到消息的时候划分成数据包再交给上层逻辑。
比如可以在发包的时候加上2个字节长度的内容,里面存上接下来的数据的长度。
以上介绍了“ CSocket的OnReceive如何实现接收完整的数据?”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/2972284.html