2

指定されたメッセージ仕様で要求メッセージを作成し、サーバーの思考cソケットに送信するにはどうすればよいですか?クライアントとサーバーの通信にはバイナリプロトコルが採用されています。次のアプローチは正しいですか?

与えられたメッセージ仕様:

フィールド形式の長さの値
------------ ------ ------ --------
requesID Uint16 2 20
requestNum Uint16 2100
requestTitle文字列10データsring

    /**************アプローチ1****************/
    typedef unsigned short uint16;
    typedef struct {
        uint16 requesID [2];
        uint16 requestNum [2];
        unsigned char requestTitle [10];
    } requesMsg;
    …
    requesMsg rqMsg;

    memcpy(rqMsg.requesID、 "\ x0 \ x14"、2); // 20
    memcpy(rqMsg.requesNum、 "\ x0 \ x64"、2); // 100
    memcpy(rqMsg.requesTitle、 "title01"、10);
    …
    send(sockfd、&rqMsg、sizeof(rqMsg)、0);

    /**************アプローチ2****************/
    unsigned char rqMsg [14];
    memset(rqMsg、0、14);
    memcpy(rqMsg、 "\ x0 \ x14"、2);
    memcpy(rqMsg + 2、 "\ x0 \ x64"、2);
    memcpy(rqMsg + 4、 "title01"、10);
    …
    send(sock、&rqMsg、sizeof(rqMsg)、0);
    
4

2 に答える 2

3

長さの列は長さをバイト単位で示しているように見えるので、uint16 を受け取った場合は 2 バイトを受け取ります。

最初のアプローチは、データ構造のアライメントによって深刻な問題につながる可能性があります。私があなたの立場にあった場合、2 番目のアプローチを好み、自分でバイトをバイト配列に入力します。

ここでのフィールドへの入力に関する一般的な注意事項: uint16 などの「ネイティブ」フィールドに memcpy を使用しても意味がありません。動作する可能性はありますが、単に実行時間が無駄になります。次のような値を割り当てるだけで、構造体のフィールドに入力できますrqMsg.requesID = 20;

もう 1 つの問題は、バイナリ プロトコルのバイト オーダーまたはエンディアンの問題です。

パッケージ全体として、構造体のフィールドを取得する「serializeRequest」関数を実装し、プロトコルに従ってバイト配列に変換します。

于 2013-01-24T09:50:01.017 に答える