拼包处理通用函数

主要是工作用到的,通用的,可能跨应用场合的类或函数

下面这个主要是用来处理接收对拼包的处理过程:

 

//===========================================================================================================
// Name     :ST_MemData
// Created    :10:5:2011   11:34
// Author    :JiQiuBo

// Purpose    :used in netlayer.cpp, when camera sending data to ARM, the netlayer object parse the data package;
// Modify    :
//===========================================================================================================
struct ST_MemData
{
    BYTE *  m_pData;
    int     m_nLen;                  //当前缓冲区大小
    int     m_nPointPos_DataEnd;     //当前数据指针的结束位置
    int     m_nJPGSize;
    
    ST_MemData()
    {
        m_pData = NULL;
        m_nLen = 0;
        m_nPointPos_DataEnd = 0;
        m_nJPGSize = 0;
    };
    
    ~ST_MemData()
    {
        ReleaseSpace();
    };
    
    bool AllocSpace(int nLen)
    {
        ReleaseSpace();
        
        m_pData = new BYTE[nLen];
        m_nLen = nLen;
        m_nPointPos_DataEnd = 0;
        m_nJPGSize = 0;

        return true;
    };
    
    bool ReleaseSpace()
    {
        if( m_pData != NULL )
        {
            delete m_pData;
            m_pData = NULL;
        }
        m_nLen = 0;
        m_nPointPos_DataEnd = 0;
        m_nJPGSize = 0;

        return true;
    };
};

 

 

bool CProtocol::ReceivedIsCompletePackage( LPBYTE lpBuff, DWORD dwSize )
{

    BYTE * pPackData = lpBuff;
    int nPackSize = dwSize;
    
    if (m_oMemData.m_pData == NULL)
    {
        //this->m_oMemData.ReleaseSpace();
        this->m_oMemData.AllocSpace(1024 * 1024 * 2);
    }
    
    if (m_oMemData.m_nPointPos_DataEnd + nPackSize > m_oMemData.m_nLen)
    {
        m_oMemData.m_nPointPos_DataEnd = 0;
        printf("warning! m_nPointPos_DataEnd + nPackSize > m_oMemData.m_nLen =============================\r\n");
    }
    
    m_oMemData.m_nJPGSize = 0;
    
    memcpy(m_oMemData.m_pData + m_oMemData.m_nPointPos_DataEnd, pPackData, nPackSize);
    m_oMemData.m_nPointPos_DataEnd += nPackSize;
    
    BYTE * lpPackageHeader;
    lpPackageHeader = (BYTE *) m_oMemData.m_pData;
    
    
    const int PACK_HEADER_SIZE = CNST_LEGTH_PACKHEADER;
    if (nPackSize < PACK_HEADER_SIZE)
        return nPackSize;
    
    Enthernet_FrameHead framehead; memset( &framehead, 0, sizeof( Enthernet_FrameHead) );

    int nJPGDataPos = 0;//PACK_HEADER_SIZE + lpPackageHeader->numberofrecord * sizeof (YhteCarRecordDataStr);
    
    if (lpPackageHeader[0] == 0xaa && lpPackageHeader[1] == 0x55 && 
        lpPackageHeader[2] == 0xaa && lpPackageHeader[3] == 0x55)
    {
        //判断数据的合法性,如头部分信息的合理性,或校验位是否正确
        //从包头中得到数据长度
        DWORD dwDataLen = 0;
        
        memcpy(&framehead,lpPackageHeader+3,2);
        memcpy(&dwDataLen,lpPackageHeader+5,4); //数据包长度
        //wCrcValue=gen_crc(lpPackageHeader+3,6); //求校验值

        m_oMemData.m_nJPGSize = dwDataLen;
        nJPGDataPos = PACK_HEADER_SIZE;

        /*
        if (lpPackageHeader->numberofrecord < 8 && lpPackageHeader->numberofrecord > 0)
        {
            //接收到头
            m_oMemData.m_nJPGSize = lpPackageHeader->jpgsize;
            nJPGDataPos = PACK_HEADER_SIZE + lpPackageHeader->numberofrecord * sizeof (YhteCarRecordDataStr);
            
            //printf("OK! Find header!==================================================\r\n");
        }
        else
        {
            printf("warning! in package header ,the jlpPackageHeader->numberofrecord,s value is not right!==================================================\r\n");
            
            nJPGDataPos = 0;
            
            //去除该头数据
            if (m_oMemData.m_nPointPos_DataEnd - PACK_HEADER_SIZE >= 0)
            {
                memmove(m_oMemData.m_pData, m_oMemData.m_pData + PACK_HEADER_SIZE, m_oMemData.m_nPointPos_DataEnd - PACK_HEADER_SIZE);
                m_oMemData.m_nPointPos_DataEnd = m_oMemData.m_nPointPos_DataEnd - PACK_HEADER_SIZE;
            }
            return m_oMemData.m_nPointPos_DataEnd;
        }
        */
    }
    else
    {
        printf("warning! the 0 pos is not header. Begin find header..................................................\r\n");
        
        bool bFoundHeader = false;
        
        //
        BYTE * pTmpData = m_oMemData.m_pData;
        int noffset = 0;
        while (m_oMemData.m_nPointPos_DataEnd >= m_oMemData.m_nJPGSize + nJPGDataPos + noffset )
        {
            BYTE * lpPackageHeader;
            lpPackageHeader = (BYTE *)( pTmpData + noffset);
            if (lpPackageHeader[0] == 0xaa && lpPackageHeader[1] == 0x55 && 
                lpPackageHeader[2] == 0xaa && lpPackageHeader[3] == 0x55)
            {
                //判断数据的合法性,如头部分信息的合理性,或校验位是否正确
                //if (lpPackageHeader->numberofrecord < 8 && lpPackageHeader->numberofrecord > 0)  //不做过多判断,找到头就认为是正确的
                {
                    //找到位置
                    memmove(m_oMemData.m_pData, m_oMemData.m_pData + noffset, m_oMemData.m_nPointPos_DataEnd - noffset);
                    m_oMemData.m_nPointPos_DataEnd = m_oMemData.m_nPointPos_DataEnd - noffset;
                    
                    printf("OK! found the header!==================================================\r\n");
                    
                    bFoundHeader = true;
                    break;
                }
            }
            noffset++;
        }
        
        if( !bFoundHeader )
            return false;
    }
    
    
    if (m_oMemData.m_nJPGSize > 0 && m_oMemData.m_nJPGSize < m_oMemData.m_nLen && m_oMemData.m_nPointPos_DataEnd >= m_oMemData.m_nJPGSize + nJPGDataPos)
    {//一个完整的数据包
        
        /*
        YhteDSPRealDataPackageHeaderStruct * lpPackageHeader2;
        lpPackageHeader2 = (YhteDSPRealDataPackageHeaderStruct *) m_oMemData.m_pData;
        if ( lpPackageHeader2->header != constHeartPackage.header || lpPackageHeader2->check != constHeartPackage.check)
        {
            printf( "warning!  header is not right!======================================================" );
            return m_oMemData.m_nPointPos_DataEnd;
        }
        */
        
        //SaveDataToFile(m_oMemData);
        ParsePackage( m_oMemData.m_pData, m_oMemData.m_nPointPos_DataEnd, framehead );
        
        if (m_oMemData.m_nPointPos_DataEnd - m_oMemData.m_nJPGSize - nJPGDataPos >= 0)
        {
            memmove(m_oMemData.m_pData, m_oMemData.m_pData + m_oMemData.m_nJPGSize + nJPGDataPos, m_oMemData.m_nPointPos_DataEnd - m_oMemData.m_nJPGSize - nJPGDataPos);
            m_oMemData.m_nPointPos_DataEnd = m_oMemData.m_nPointPos_DataEnd - m_oMemData.m_nJPGSize - nJPGDataPos;
        }
        else
        {
            m_oMemData.m_nPointPos_DataEnd = 0;
        }
    }
}

 

这个函数还可进一步完善为模板格式,可以处理各种格式的包头和数据,包头1+信息段+数据等格式。

 

 

 

 

posted @ 2012-04-15 21:42  jqb  阅读(421)  评论(1编辑  收藏  举报