Если бы это название не смутило вас, я посмотрю, что я могу здесь сделать. У меня есть источник C ++ DLL, который передает TCP-трафик на сервер. Я считаю, что все соответствующие C ++-коды приведены ниже:
#define HRD_MSG_SANITY1 0x1234ABCD #define HRD_MSG_SANITY2 0xABCD1234 typedef struct{ unsigned int nSize; unsigned int nSanity1; unsigned int nSanity2; unsigned int nChecksum; WCHAR szText[1]; } HRD_MSG_BLOCK; CString strMessage = "this is a test\n"; // I added this - the rest of the code // to determine this is unnecessary for // the context of this question. // // Allocate. // int nMsgBytes = sizeof(HRD_MSG_BLOCK) + sizeof(TCHAR) * (strMessage.GetLength() + 1); HRD_MSG_BLOCK* pMsgBlock = (HRD_MSG_BLOCK*) new BYTE[nMsgBytes]; BYTE* pMsgBuffer = (BYTE*)pMsgBlock; ZeroMemory(pMsgBlock, nMsgBytes); pMsgBlock->nSize = nMsgBytes; pMsgBlock->nSanity1 = HRD_MSG_SANITY1; pMsgBlock->nSanity2 = HRD_MSG_SANITY2; pMsgBlock->nChecksum = 0; _tcscpy(pMsgBlock->szText, strMessage); for (int nSendLoop = 0; (nSendLoop < MAX_SENDS) && (nToSend > 0); nSendLoop++) { // // Send data to this port, max of 32k (0x8000). // int nSendSize = min(nToSend, 0x8000); int nSentCount = (int)::send(g_socket, (char*)&pMsgBuffer[nSent], nSendSize, 0); // // Error. // if (nSentCount == SOCKET_ERROR) { CSocketError error(::WSAGetLastError()); // // Report the error. // g_strLastError.Format(_T("Error sending %u bytes to socket %u - %s"), nSendSize, g_socket, error.Text()); } else { nSent += nSentCount; nToSend -= nSentCount; } }
То, что я пытаюсь сделать, это сделать то же самое через PHP. Вот код PHP:
class HRD_MSG_BLOCK { public $nsize; public $nSanity1; public $nSanity2; public $nChecksum; public $szText; } $string = "this is a test\n"; $pMsgBlock = new HRD_MSG_BLOCK(); $nMsgBytes = 20 + (2*(strlen($string)+1)); // I determined this by comparing to // actual size of TCHAR = 2 and actual // size of pMsgBlock = 20 in Visual Studio $pMsgBlock->nSize = $nMsgBytes; $pMsgBlock->nSanity1 = 0x1234ABCD; $pMsgBlock->nSanity2 = 0xABCD1234; $pMsgBlock->nChecksum = 0; $pMsgBlock->szText = utf8_encode($string); $binarydata = pack("C*", $pMsgBlock);
Затем я создаю сокет и использую socket_write
для отправки $binarydata
.
Очевидно, я не могу использовать pack()
, потому что я не могу преобразовать объект класса ($ pMsgBlock) в int (который требуется в качестве второго аргумента для pack ()). Я использовал utf8_encode (), потому что в документации DLL говорится:
szText – это текст, отправляемый как строка UNICODE (широкая).
У меня возникли проблемы с определением того, что C ++ DLL отправляет в сокет, поэтому я в основном предполагаю, что мне нужно отправить в PHP.
Я мог бы использовать помощь, определяющую то, что точно передает код на C ++, и как я могу сделать то же самое в PHP.
Благодарю.
Вы не можете упаковать () целый объект, но вы можете pack () и объединить элементы. Итак, что-то вроде
$packed = pack('I', $pMsgBlock->nSize) .pack('I', $pMsgBlock->nSanity1) .pack('I', $pMsgBlock->nSanity2) .pack('I', $pMsgBlock->nChecksum) .mb_convert_encoding($pMsgBlock->szText, 'UTF-16');