我正在尝试通过 udp 实现距离矢量路由。我有以下结构:
struct cost_info {
uint8_t id;
uint8_t pad;
uint16_t cost;
}__attribute__((__packed__));
struct advertisement_packet {
uint8_t type;
uint8_t version;
uint16_t num_updates;
struct cost_info data[];
}__attribute__((__packed__));
所以数据包是 1 字节类型,1 字节版本,2 字节更新计数,然后是 4*更新计数字节的数据。我正在使用灵活的数组成员,这样我就可以做到
sendto(fd, pkt, sizeof(struct advertisement_packet) + pkt->num_updates * sizeof(struct cost_info), 0, addr, sizeof(struct sockaddr_in));
并在一个数据包中发送整个内容。需要发送一个数据包。我能够使用wireshark 验证数据是否正确发送。在接收端,我做了两个接收。第一个获取前 4 个字节,因此我可以知道需要多少更新。然后我相应地调整接收器缓冲区的大小并接收 4*num_updates 字节。问题是第二次接收用零填充我的缓冲区!如果我期望 12 个字节的数据,我会得到 12 个字节的零。下次我从该套接字读取时,我会按预期获得下一个数据包的开头。为什么会发生这种情况?
如果需要,这是我的接收代码。
recvfrom(i, pkt, sizeof(struct advertisement_packet),0,NULL,0);
//reallocate more space if the incoming data will need it
if (pkt->num_updates > pkt_cost_slots) {
pkt_cost_slots *= 2;
pkt = realloc(pkt,sizeof(struct advertisement_packet) + sizeof(struct cost_info) * pkt_cost_slots);
assert(pkt);
}
//receive data
recvfrom(i,pkt->data,pkt->num_updates * sizeof(struct cost_info),0,NULL,0);