• 一个C++版的网络数据包解析策略


    C++版的网络数据包解析策略(升级版)

    一、数据包格式形如下图

    二、代码

    int ReceiveFromRemoteEndPoint()
    {     
        int nPackageDataLength = 0; 
        char *szPackageCleaner = NULL;
        char *szPackageIterator = NULL;
        do 
        {
            char *szReceiveArray = new char[RECEIVED_BUFFER_LENGTH]();
            int nReceiveLength = RECEIVED_BUFFER_LENGTH; 
            nReceiveLength = Receive(szReceiveArray, nReceiveLength, TIMEOUT);
            if (nReceiveLength <= 0)
            {
                Log("Recveived Time-Out(%d)...", nReceiveLength);   
                delete[] szReceiveArray;
                break;
            }
            Log("Received (%d) Bytes", nReceiveLength);  
        
            char *szReceive = szReceiveArray;
    
            do 
            {
                if(nPackageDataLength == 0)
                { 
                    if(szReceive[0] != HEADER) 
                    {
                        Log("Package Data Header-Analysis Error, Size(%d).", nReceiveLength); 
                        break;  
                    }
                    if(nReceiveLength < PACKHEADERLENGTH)
                    {
                        Log("Package Data Length-Analysis Error, Size(%d).", nReceiveLength); 
                        break;   
                    }
    
                    //offset HEADER length
                    char *szPackageDataLength = szReceive + sizeof(char);
    
                    //包数据的长度(不包含包头长度)
                    LengthResolve(szPackageDataLength, nPackageDataLength); 
    
                    szPackageCleaner = new char[nPackageDataLength + PACKHEADERLENGTH + 1]();
                    szPackageIterator = szPackageCleaner;
    
                    memcpy(szPackageIterator, szReceive, PACKHEADERLENGTH);
                    szPackageIterator += PACKHEADERLENGTH;
    
                    szReceive += PACKHEADERLENGTH;
                    nReceiveLength -= PACKHEADERLENGTH;
                } 
                //已接收的包数据长度 < 包数据长度 = 一个不完整的包 
                if(nReceiveLength < nPackageDataLength)
                {   
                    memcpy(szPackageIterator, szReceive, nReceiveLength);
    
                    szPackageIterator += nReceiveLength;
                    nPackageDataLength -= nReceiveLength;
    
                    szReceive += nReceiveLength;
                    nReceiveLength -= nReceiveLength;
                }
                else//(nReceiveLength >= nPackageDataLength)
                {
                    //已接收的包数据长度 == 包数据长度 = 一个完整的包  
                    //已接收的包数据长度 > 包数据长度  = 至少有一个完整的包 + 至少一个数据片段 
                    memcpy(szPackageIterator, szReceive, nPackageDataLength);
                    //szPackageIterator += nPackageDataLength;
                    Resolve(szPackageCleaner, (szPackageIterator - szPackageCleaner) + nPackageDataLength);
    
                    szReceive += nPackageDataLength;
                    nReceiveLength -= nPackageDataLength;
    
                    nPackageDataLength = 0;
    
                    delete[] szPackageCleaner;
                    szPackageCleaner = NULL; 
                }            
    
            }while(nReceiveLength > 0);    
    
            delete[] szReceiveArray;
            Sleep(8);
    
        }while(IsStop);//Receiving
        
        if(szPackageCleaner != NULL)
            delete[] szPackageCleaner;
        
        return 0;
    } 

    三、说明

    网络数据包接收,最好是有超时机制的,比如2秒左右。

    if(nReceiveLength < PACKHEADERLENGTH)
    {
             Log("Package Data Length-Analysis Error, Size(%d).", nReceiveLength);
             //这里会出现些问题 
             break;   
    }

    问题描述:
      假如一个完整的数据包解析后,剩余的接收长度 < PACKHEADERLENGTH, 即包头HEADER校验正确,但是解析包数据长度的时接收到的数据不足以解析出

    数据要接收的长度。此策略会丢弃包数据至下一个正确的包被正确解析,这个和缓冲区设置的长度是没有直接关系的,当然长度要大于PACKHEADERLENGTH.

    要解决这个问题,可以在 break; 之前保存这个数据片,并在和下次接收的拼接解析数据长度。

    此策略不是最好的更不是最优的,更好的可能就在你那里呢,有你的指点我相信会更好的。

  • 相关阅读:
    Unable to load dbxmss.dll (ErrorCode 16). It may be missing from the system Path
    同一网内机器无法连通解决一例
    Day.24
    Day.24
    Day.23
    Day.22
    Day.23
    Day.21
    Day.22
    Day.01-Day.20
  • 原文地址:https://www.cnblogs.com/wjshan0808/p/6580638.html
Copyright © 2020-2023  润新知