0

UDP ソケット経由で構造体を送信しようとしています。

struct パケット { int seqnum; char data[BUFFERSIZE]; };

だから私が持っている送信者に

bytes = sizeof(packet);
char sending[bytes];
bzero(sending, bytes);
memcpy((void *) sending, (void *) &packet, sizeof(bytes));
bytes = sendto(sockfd, sending, sizeof(sending), 0,
    (struct sockaddr *) &client, clientSize);

だから私はそれが私の構造体をChar []にコピーすることを望んでいます。

私が持っている受信機で

int bytes;
bytes = sizeof(struct Packet);
char recv[bytes];
bytes = recvfrom(sockfd, recv, bytes, 0,
    (struct sockaddr *) &client, &clientSize);
memcpy((void *) currentpkt, (void *) recv, bytes);

ただし、レシーバーではmemcpy((void *) currentpkt, (void *) recv, bytes); を使用します。エラーが発生します:

エラー: ポインター型に変換できません

私は何を間違っていますか?UDP ソケット経由で構造体を送信するより良い方法はありますか?

***** アップデート *****

回答ありがとうございます。最後に「&」を見逃しましたが、コードは次のようになりました。

送信者:

void udt_send(struct Packet packet) {
    int bytes;
    bytes = sendto(sockfd, (char *) &packet, sizeof(packet), 0,
            (struct sockaddr *) &client, clientSize);
}

レシーバー:

bytes = recvfrom(sockfd, (char *) &currentpkt, bytes, 0,
        (struct sockaddr *) &client, &clientSize);

C では、それを char にキャストしてバイトを送信できるのは素晴らしいことです。

4

4 に答える 4

3

currentpkt構造体型です。これを機能させるには、構造体へのポインターを取得する必要があります。

memcpy(&currentpkt, recv, bytes);

2 番目の質問については、他にもいくつか問題があります。よりも多くのバイトをパケットで受信した場合はどうなりますsizeof(struct Packet)か? 今書かれているように、構造体をオーバーランします。

クライアント アプリケーションとサーバー アプリケーションが異なるコンパイラや設定を使用してコンパイルされている場合、またはエンディアンが異なるプラットフォームでコンパイルされている場合はどうなるでしょうか。この場合、構造体は 2 つのプラットフォームで異なるサイズである可能性があり、メモリ内で異なる方法でレイアウトされる可能性があります。

于 2009-12-07T04:29:15.050 に答える
1

ですから、それcurrentpktstruct Packetであり、あなたが本当に言いたかったことだと思います&currentpkt

また、memcpy()すでにvoid *パラメーターがあるため、(void *)キャストは必要ありません。

于 2009-12-07T04:28:28.360 に答える
0

構造体全体からmemcpyを実行することは、本当に悪です:-)。まず、アーキテクチャによってデータの配置が異なる場合があります。反対側でアーキテクチャが異なる場合はどうなりますか?また、__ packedなどのキーワードを使用することは、異なるコンパイラ間で移植できません。

私が知っているように、最良の方法は、PHPパック/アンパックのようなAPIを使用することです。これにより、__ packedなどのコンパイラ固有の醜いキーワードを使用せずに、コードを真に移植可能にします。

ネット上でCのパック/アンパックが見つからなかったので、自分で作成しました。

たとえば、バイナリデータから2つの単語を解凍するには、次のようにします。

   pbuf_unpack(p_bts, "ww", &hdr, &ver); 

どこ

   p_bts is binary data
   "ww" describes the data structure
   hdr and ver is where to put the datause an API like the PHP pack/unpack. 

もう1つのより広範な例:

   pbuf_unpack(p_entry, "bbbbbbbbww",
      &atrb_mbr.def_boot_par, &atrb_mbr.head_start, &atrb_mbr.sec_start,
      &atrb_mbr.cyl_start, &atrb_mbr.type, &atrb_mbr.head_end, 
      &atrb_mbr.sec_end, &atrb_mbr.cyl_end, &atrb_mbr.start_sec_pbr,
      &atrb_mbr.sec_per_par);

パッキングは非常に簡単です:

   pbuf_pack(boot_buf, "sdsdhbhbhhbhhhwwbbbwsdsd", sizeof(fat_jmp_boot_t), 
      boot.jmp, sizeof(fat_oem_nm_t), boot.oem_nm, boot.n_bps, boot.n_spc, 
      boot.n_rs, boot.n_fs, boot.n_rde, boot.n_ts16, boot.media_des, 
      boot.n_fatsz16, boot.n_spt, boot.n_hds, boot.n_hs, boot.n_ts32, 
      boot.drv_no, boot.rsrvd1, boot.boot_sig, boot.vol_id, 
      sizeof(fat_vol_lbl_t), boot.lbl, sizeof(fat_vol_type_t), boot.type);

ポータブルコードを作成するだけでなく、美しいです;)

于 2009-12-07T12:50:00.790 に答える
0

memcpy((void *) currentpkt, (void *) recv, bytes);

エラー メッセージは、キャストの問題を示しています。((void*) に変換しても問題ありません)recvであるため、問題ありません。char[]問題はcurrentpkt、ポインター型であってはならないことです。

スニペットで宣言されていないので、それが何であるかはわかりませんが、そこから始めます。

于 2009-12-07T04:30:01.010 に答える