我想通過udp實現距離矢量路由。我有以下結構:recvfrom用零填充緩衝區
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);
試過這個。我能夠獲得大小,然後第二次讀取全部金額。不幸的是,儘管第二次讀取表明它已經獲得了全部16個字節,但數據被清零。 – Sandles
@Sandles,如果您可以在接收方驗證,例如通過wireshark,傳入的數據是按照您的期望結構化的,那麼我最好的猜測是接收者對發佈者的'struct advertisement_packet'和/或'struct cost_info'的佈局有不同的想法。這可能會使*看起來*收到的數據全部爲零。我建議通過將'pkt'強制轉換爲'unsigned char *'來檢查實際收到的數據,並逐字節地檢查。 –
Welp。我鑄造它,它肯定是獲取數據。我仍然需要弄清楚爲什麼我的結構訪問返回0,但我得到的數據,這是重要的。謝謝!! – Sandles