3

いくつかの信頼できるデータ転送プロトコルの実装に関する情報を保持する RDT ヘッダーのクラスがあります。その情報 (合計 12 バイト) を送信バッファーにアタッチして、ソケット経由で転送する必要があります。これを行うためにmemcpyを使用しようとしていますが、何らかの理由でバッファ内にジャンクが残るだけです。以下は、動作していないコード行です。(RDT_HDR_SIZE は 12 として定義されます)。

この関数に渡される変数の定義。

char payload[] = "sample code sample code";
int payload_size = sizeof(payload) ; 
int pktsize = payload_size + sizeof( RdtHeader )+1 ; // 1 byte for NULL-terminated
char * send_buf = new char[pktsize];

問題が発生している memcpy の関数。

unsigned int Sender::CreateSegment( char * buf, 
         char payload[], int payload_size, unsigned long seqnum ) {
     RdtHeader * header = (RdtHeader *) buf; 
     // set rdt fields:
     header->ack = 0; 
     header->fin = 0; 
     header->ok = 0; 
     header->seq = seqnum; 
     header->win = 0;
     header->syn = 0;
     memcpy( buf+RDT_HDR_SIZE, payload, payload_size );

     return (payload_size + RDT_HDR_SIZE + 1);
}

RDT_HDR_SIZE を取り出すと、ペイロードは適切に buf に割り当てられますが、すべてのヘッダー フィールドが消去されます。これを機能させる方法はありますか?

ありがとう、

エリック R.

編集:

これが私の RdtHeader クラスのコードです。おそらく役に立つでしょう。

class RdtHeader{    // 12-byte header 
public: 
//1-byte flags field
    u_char protocol:2;      // 2 bits: protocol type = 0 for RDT3, 1 for GBN, and 2 for STCP    
    u_char syn:1;           // 1 bit: SYN = 1 for connection setup  
    u_char fin:1;           // 1 bit: FIN = 1 for termination
    u_char ok:1;            // 1 bit: OK = 1 receiver agrees, SYN_OK or FIN_OK
    u_char reserved:3;      // 3 bits: unused

    u_char unused;          // 1-byte unused filed; 

    u_short win;            // 2-byte receiver window size (the number of packets)
    u_long seq;             // 4-byte sequence number
    u_long ack;             // 4-byte ack number
}; 
4

3 に答える 3

2

Markが言ったように、sizeof(RdtHeader)を見てください。構造体の内部に(特にそこに長いintがあるため)計算を破棄するパディングがある可能性があります。

しかし、それ以外は、ここでは明らかな問題は見られません。それが可能な環境で実行している場合は、いくつかのプリントアウトを追加しようとするか、デバッガーを試してみます。おそらく、本当の問題はコードの他の場所にあります。

于 2010-10-12T04:35:00.780 に答える
2

これはあまりにも明白かもしれませんが、バッファを正確にどのように調べているのでしょうか?

やってみました

printf( "%s\n", send_buf + sizeof(RdtHeader) );

?

あなたが代わりにやっているなら...

printf( "%s\n", send_buf );

...その後、後者の呼び出しが出力している「文字列」のゼロターミネータとしてフィールドが機能するため、(正しい操作で)ゴミだけが表示されることを期待する必要があります。win

乾杯 & hth.,

– アルフ

于 2010-10-12T05:36:48.257 に答える
0
memcpy(header + 1, payload, payload_size + 1);
return sizeof(*header) + payload_size + 1;
  • You're mysteriously returning an extra 1, suggesting the payload is a null-terminated string. You might want to copy that terminator, so it's included in the last memcpy parameter.
  • By using the header pointer to calculate the memcpy destination, you'll never have to cast if types change, in particular if you change the type of buf. You can rely on the fact that C++ allows X * to degrade to void * to avoid ugly casting.
于 2010-10-12T04:39:13.827 に答える