我正在尝试通过UDP套接字发送我的结构。
struct Packet { int seqnum; char数据[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 *) ¤tpkt, bytes, 0,
(struct sockaddr *) &client, &clientSize);
在C中很好,我们可以将它转换为char并将字节发送过来。
答案 0 :(得分:3)
currentpkt
是结构类型;你需要得到一个指向结构的指针才能使它工作:
memcpy(¤tpkt, recv, bytes);
对于第二个问题,您还有其他一些问题。如果您收到的数据包中的字节数多于sizeof(struct Packet)
,该怎么办?正如现在所写,你将超越你的结构。
如果使用不同的编译器或设置或具有不同字节顺序的平台编译客户端和服务器应用程序,该怎么办?在这种情况下,结构在两个平台上的大小可能不同,并且可能以不同的方式在内存中布局。
答案 1 :(得分:1)
所以我认为currentpkt
是struct Packet
,你真的想说¤tpkt
。
我可能还会注意到memcpy()
已经有void *
个参数,因此不需要(void *)
强制转换。
答案 2 :(得分:0)
memcpy((void *) currentpkt, (void *) recv, bytes);
您的错误消息表明存在投射问题。 recv
是好的,因为它是char[]
(转换为(void *)没问题)。问题必须是currentpkt
不能是指针类型。
它没有在你的片段中声明,所以我不知道它是什么,但我会从那里开始。
答案 3 :(得分:0)
从整个结构中做memcpy真的很邪恶:-)。首先,根据架构,数据可能会有所不同。如果另一方面的架构不同怎么办?使用__packed等关键字也不能在不同的编译器之间移植。
据我所知,最好的是使用像PHP pack / unpack这样的API。这使代码真正可移植,而不使用编译器特定的丑陋关键字,如__packed。
我没有在网上找到任何包装/解包装,所以我自己写了。
例如,从二进制数据中解压缩两个单词:
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);
它不仅创造了可移植的代码,而且还很漂亮;)