1

私のソケットプログラムに関する質問: 私は... 内部クラスを持っています... 私は推測します (申し訳ありませんが、Java から C/C++ に来ています)。

typedef struct {
    enum {Request, Reply} messageType;
    unsigned int RPCId;
    unsigned int procedure;
    int arg1;
    int arg2;
} RPCMessage;

UDP ソケットを介して送信された要求への応答として RPCMessage を受信することを期待しています。現在、次のコードを含むメッセージを受け取ります。

/* Recv a response */
fromSize = sizeof(fromAddr);
if ((respSize = recvfrom(sock, buffer, maxSize, 0, (struct sockaddr *)&fromAddr,
        &fromSize)) != messageSize)
    DieWithError("recvfrom() failed");

ここでのバッファは char 配列であることに注意してください。私が欲しいのは、受信したメッセージを RPCMessage に戻すことです...だから私は試しました:

RPCMessage receivedMessage = (RPCMessage)buffer;

これはコンパイラを喜ばせていません... char 配列内のこれらのバイトを RPCMessage とそのフィールドに戻す正しい方法は何ですか?

4

2 に答える 2

3

選択肢はほとんどありません。オプション #1 は、バッファの内容をコピーすることです。

RPCMessage receivedMessage;
memcpy(&receivedMessage, buffer, sizeof(receivedMessage));

オプション #2 は、char バッファーへのポインターを RPCMessage 型へのポインターとして再解釈することです。

RPCMessage *receivedMessage = (RPCMessage *)buffer;

オプション番号 #3 は、バッファーを手動で解析して class のフィールドにすることRPCMessageです。

オプション #1 と #2 については、構造体/フィールドのパディング、アーキテクチャのアライメント要件などに注意する必要があります。

于 2012-10-14T02:14:02.420 に答える
1

まず、生のバイトを扱っているので、unsigned char 配列を使用し、偶発的な符号拡張は使用しないでください。

次に、そのバッファーを参照するためのポインター型が必要です。

RPCMessage* receivedMessage = (RPCMessage*)buffer;

そして最後に、送信者と受信者が同じバイトパッキングを使用していることを確認してください。同様に、上記を実行する前に、RPCMessage のすべてのデータを受信したことを確認してください。

注: 通常、バッファからバイトを逆アセンブルし、RPCMessage 構造体で受信データを作成する方がよいでしょう。ただし、両方の側でパッキングやエンディアンなどについて合意していることが確実にわかっている場合を除きます。

于 2012-10-14T02:11:57.023 に答える