0

我正在尝试通过 UDP 套接字发送我的结构。

结构数据包 { int seqnum; 字符数据[缓冲区大小];};

所以在我的发件人上

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);

对于第二个问题,您还有其他一些问题。如果您在数据包中收到的字节数多于sizeof(struct Packet)怎么办?正如现在所写的那样,您将超出您的结构。

如果客户端和服务器应用程序是使用不同的编译器或设置编译的,或者在具有不同字节序的平台上编译怎么办?在这种情况下,结构在两个平台上的大小可能不同,并且在内存中的布局也可能不同。

于 2009-12-07T04:29:15.050 回答
1

所以我想那currentpkt是一个struct Packet,你真的想说&currentpkt

我可能还会注意到memcpy()已经有void *参数,所以(void *)不需要强制转换。

于 2009-12-07T04:28:28.360 回答
0

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

您的错误消息表明投射问题。recv没关系,因为它是char[](转换为(void *)没有问题)。问题一定是currentpkt不能是指针类型。

它没有在您的代码段中声明,所以我不知道它是什么,但我会从那里开始。

于 2009-12-07T04:30:01.010 回答
0

从整个结构中执行 memcpy 确实是邪恶的 :-)。首先,数据可能会因架构而异。如果另一边的架构不同怎么办?此外,使用诸如 __packed 之类的关键字也不能在不同的编译器之间移植。

据我所知,最好的方法是使用像 PHP 打包/解包这样的 API。这使得代码真正可移植,而无需使用编译器特定的丑陋关键字,例如 __packed。

我在网上没有找到任何 C 的打包/解包,所以我自己写了。

例如从二进制数据中解压缩两个字:

   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. 

另一个更广泛的例子:

   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 回答