如何将 c 中的 char[] 复制到我的结构中

发布于 2024-08-13 06:23:39 字数 1311 浏览 3 评论 0原文

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

结构数据包{ int 序列号; 字符数据[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 并发送字节,这很好。

I am trying to send my struct over a UDP socket.

struct Packet {
int seqnum;
char data[BUFFERSIZE];
};

So on the sender I have

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

So I'm hoping that copies my struct into the Char[].

On the receiver I have

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

However on the receiver with memcpy((void *) currentpkt, (void *) recv, bytes); I get an error:

error: cannot convert to a pointer type

What am I doing wrong? Is there a better way to send my struct over a UDP socket?

***** UPDATE *****

Thanks for the answers everyone. In the end I missed the '&' but my code now looks like this.

Sender:

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

Receiver:

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

In C its nice that we can just cast it to a char and send the bytes over.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

握住我的手 2024-08-20 06:23:39

currentpkt 是结构体类型;您需要获得指向该结构的指针才能使其正常工作:

memcpy(¤tpkt, recv, bytes);

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

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

currentpkt is of struct type; you need to get a pointer to the struct to get this to work:

memcpy(¤tpkt, recv, bytes);

For your second question, you have some other problems. What if you receive more bytes in a packet than sizeof(struct Packet)? As it's written now, you'll overrun your struct.

What if the client and server applications are compiled using different compilers or settings, or on platforms with different endianness? In this case, the struct might be different sizes on the two platforms and may be laid out in memory differently.

以歌曲疗慰 2024-08-20 06:23:39

所以我认为 currentpkt 是一个 struct Packet,并且您真正的意思是说 ¤tpkt

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

So I'm thinking that currentpkt is a struct Packet, and that you really meant to say ¤tpkt.

I might also note that memcpy() already has void * parameters, so the (void *) casts are not needed.

素染倾城色 2024-08-20 06:23:39

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

您的错误消息表明存在强制转换问题。 recv 没问题,因为它是 char[] (转换为 (void*) 没有问题)。问题肯定是 currentpkt 不能是指针类型。

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

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

Your error message indicates a cast problem. recv is ok since it's a char[] (no problem converting to (void*)). The problem must be that currentpkt must not be a pointer type.

It's not declared in your snippet so I don't know what it is, but I'd start there.

jJeQQOZ5 2024-08-20 06:23:39

从整个结构中执行 memcpy 确实是邪恶的:-)。首先,根据架构的不同,数据的对齐方式可能有所不同。如果另一侧的架构不同怎么办?此外,使用诸如 __packed 之类的关键字在不同编译器之间不可移植。

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

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

例如,从二进制数据中解压两个单词:

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

Where

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

它不仅创建可移植的代码,而且也很漂亮;)

Doing memcpy from an entire struct is truly evil :-). First of all the data might be aligned differently depending on architecture. What if the architecture is different on the other side? Also using keywords such as __packed isn't portable between different compilers.

The best, as I know, is to use an API like the PHP pack/unpack. This makes the code truly portable without using compiler specific ugly keywords such as __packed.

I didn't find any pack/unpack for C on the net so I wrote my own.

For example to unpack two words from binary data:

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

Where

   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. 

Another more extensive example:

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

Packing is very easy:

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

Not only does it create portable code but it's also beautiful;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文