If that title didn't confuse you, I'll see what I can do here. I have the source of a C++ DLL that passes TCP traffic to a server. I believe all the relevant C++ code is below:
#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;
}
}
What I am trying to do is accomplish the same thing via PHP. Here is the PHP code:
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);
I then create the socket, and use socket_write
to send $binarydata
.
Obviously, I cannot use pack()
, because I cannot convert a class object ($pMsgBlock) to an int (which is required as the second argument to pack()). I used utf8_encode() because the DLL documentation says:
szText is the text being sent as a UNICODE (wide) string.
I'm having trouble determining exactly what the C++ DLL is sending to the socket so I'm basically guessing at what I need to send in PHP.
I could use help determining what the C++ code is sending exactly, and how I can do the same in PHP.
Thanks.
You can't pack() a whole object, but you can pack() and concatenate the members. So, something like