PHP包二进制数据格式CHAR c ++

时间:2013-09-26 14:50:19

标签: php c++ sockets binary pack

我需要将c ++应用程序重写为PHP,并且在c ++中我有这种消息结构用于socket tcp / ip通信:

enter image description here

因此,要以二进制形式在一个TCP / IP连接中发送消息,我在PHP中使用此代码:

 $message = pack('N', 1431655765)                  //HEADER - uint32 ui32Synch1
    . pack('N', 2863311530)                           //HEADER - uint32 ui32Synch2
    . pack('n', 1)                                    //HEADER - uint16 ui16Version
    . pack('N', 1)                                    //HEADER - uint32 ui32Cmd;
    . pack('N', 44)                                   //HEADER - uint32 ui32BodySize
    . pack('a20', pack('c', "44436412"))              //BODY - char szLisence[20]
    . pack('a20', pack('c', "Test_Program"))          //BODY - char szApplName[20]
    . pack('I', 0);                                   //BODY - int  nRet

    echo "<br/> Correct Message - packed = " . $message . "<br/> strlen " . strlen($message);

在PHP中的方法socket_send()发送之前的消息与C ++中的消息: enter image description here

消息几乎相同,但我在“ªªªª”之后遇到问题,我做错了什么?

备注: 字节顺序:Little-Endian strlen($ message)= 62,这是正确的,因为我需要发送的消息大小,在c ++和文档中大小等于62个字节。

更新 在评论中提出要求后:

PHP代码: enter image description here

C ++代码:

按钮调用函数进行注册:

void CPMSifDlg::OnbtnReg() 
{
    SPMSifRegisterMsg *m_RegMsg;
    BYTE *pbytesSend;
    BYTE *pbytesReceive;

    m_RegMsg = new SPMSifRegisterMsg;

    UpdateData(TRUE);
    strcpy(m_RegMsg->szLicense, m_strLic);      //Build the data
    strcpy(m_RegMsg->szApplName, m_strAppl);
    m_RegMsg->nRet=0;
    SetHeader(&m_RegMsg->hdr1, CMD_REGISTER);

    pbytesSend = new BYTE[sizeof(SPMSifRegisterMsg)];
    memcpy(pbytesSend, m_RegMsg, sizeof(SPMSifRegisterMsg));     //copy m_RegMsg structure to pbytesStore

    pbytesReceive=TCPSend(pbytesSend, sizeof(SPMSifRegisterMsg));         //sends pbytesStore and receives the response

    m_RegMsg=(SPMSifRegisterMsg*)pbytesReceive;                     //copy response back to structure
    m_iRegRes=m_RegMsg->nRet;
    UpdateData(FALSE);
}

发送消息和接收响应的函数调用:

BYTE *CPMSifDlg::TCPSend(BYTE *pbytesStore, int size)
{
    BYTE *pbytes;
    BOOL bEmpty;
    int nRetVal, nRead;
    int nMsgSize;
    SPMSifHdr spHdr;

    //check endian
    if ( htonl(47) == 47 ) {
      // Big endian
    } else {
      // Little endian.
    }
    m_mySocket.Send((void*)pbytesStore, size);

    nRetVal = m_mySocket.Receive((void*)&spHdr, sizeof(SPMSifHdr), MSG_PEEK);

    if ((nRetVal >= sizeof(SPMSifHdr)) && (spHdr.ui32Synch1 == 0x55555555) && (spHdr.ui32Synch2 == 0xaaaaaaaa))
    {
        nMsgSize = spHdr.ui32BodySize + sizeof(SPMSifHdr);
        pbytes = new BYTE[nMsgSize];

        bEmpty = FALSE;
        nRead = 0;
        nRetVal = 0;
        while(!bEmpty)
        {
            nRetVal = m_mySocket.Receive(pbytes, nMsgSize);

            if (nRetVal > 0)
                nRead += nRetVal;

            if ((nRetVal <= 0) || (nRead == nMsgSize))
                bEmpty = TRUE;
            else if (nRead <= nMsgSize)
                pbytes += nRetVal;
        }

        if (nRead != nMsgSize)
            MessageBox("FAILED to Receive TCP message");
        else
            return pbytes;
    }
    return pbytesStore;
    }

解决:

在经历了一些经历后,我解决了这个问题:

  $message = pack('N', 1431655765)      //HEADER - uint32 ui32Synch1
. pack('N', 2863311530)                 //HEADER - uint32 ui32Synch1
. pack('v', 1)                          //HEADER - uint16 ui16Version
. pack('V', 1)                          //HEADER - uint32 ui32Cmd;
. pack('V', 44)                         //HEADER - uint32 ui32BodySize
. pack('a20', "44436412")               //BODY - char szLisence[20]
. pack('a20', "Test_Program")           //BODY - char szApplName[20]
. pack('I', 0);                         //BODY - int  nRet

0 个答案:

没有答案