读书人

CSocket的OnReceive怎么实现接收完整的

发布时间: 2012-03-28 15:40:03 作者: rapoo

CSocket的OnReceive如何实现接收完整的数据?
客户端的socket类继承了CSocket,在OnReceive中接收服务器发来的数据,服务器每次发过来数据的大小为6k左右,在局域网内测试的时候没什么问题,把服务器程序搭在外网测试,6k的数据大多数会被分成两次来发送,有时多有时少,这样的话,每次都不能收到完整的数据,应该怎么解决?

[解决办法]
使用TCP的话就是会有这种情况的,你需要自己处理一下。就是自己定义出消息边界,收到消息的时候划分成数据包再交给上层逻辑。

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

探讨
使用TCP的话就是会有这种情况的,你需要自己处理一下。就是自己定义出消息边界,收到消息的时候划分成数据包再交给上层逻辑。

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

[解决办法]
C/C++ code
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;}
[解决办法]
补充一下,首先要通过包头来判断是否已经收到一个完整的包了,没有收到,那就再循环等待,等到,所有的包收齐为止,再处理这个包,并丢弃这个包。
[解决办法]
自定义协议,包头+数据,包头含有数据长度信息
[解决办法]
同意5楼,我一般是这样做的,当然,有必要的话还要加校验。
[解决办法]
tcp/ip层只能保证报文或帧的完整性,而要处理业务数据的话,就需要自己设计好协议数据格式
通用做法 包头+业务数据,而包头中需要包括数整个协议的长度,才能保证业务数据的完整性,收到数据后
根据协议中的长度,循环接收,直到收完为止。

读书人网 >VC/MFC

热点推荐