2

そのタイトルがあなたを混乱させなかったら、私はここで何ができるか見てみましょう. TCP トラフィックをサーバーに渡す C++ DLL のソースがあります。関連する 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_writesend を使用します$binarydata

pack()クラス オブジェクト ($pMsgBlock) を int (pack() の 2 番目の引数として必要) に変換できないため、明らかに を使用できません。DLL のドキュメントに次のように記載されているため、utf8_encode() を使用しました。

szText は、UNICODE (ワイド) 文字列として送信されるテキストです。

C++ DLL がソケットに送信しているものを正確に判断するのに問題があるため、基本的に PHP で送信する必要があるものを推測しています。

C++ コードが正確に送信しているものと、PHP で同じことを行う方法を判断するのに役立ちます。

ありがとう。

4

1 に答える 1

2

オブジェクト全体を pack() することはできませんが、 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');
于 2012-11-27T18:24:45.843 に答える