我需要将c ++应用程序重写为PHP,并且在c ++中我有这种消息结构用于socket tcp / ip通信:
因此,要以二进制形式在一个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 ++中的消息:
消息几乎相同,但我在“ªªªª”之后遇到问题,我做错了什么?
备注: 字节顺序:Little-Endian strlen($ message)= 62,这是正确的,因为我需要发送的消息大小,在c ++和文档中大小等于62个字节。
更新 在评论中提出要求后:
PHP代码:
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