2015-02-06 61 views
0

我正在使用必須能夠使用UDP與傳統計算機進行通信的嵌入式框。當該框發送大型UDP消息(需要分片)時,每個分片都包含一個UDP頭。因此,如果我想將發送大量數據包,它會被分片這樣的:在每個片段上發送帶有UDP頭部的分段數據報

[eth hdr][ip hdr][udp hdr][ data 1 ] /* first fragment */ 
[eth hdr][ip hdr][udp hdr][ data 2 ] /* second fragment */ 
[eth hdr][ip hdr][udp hdr][ data 3 ]  /* last fragment */ 

我明白,這是不是習慣,因爲平時UDP報頭只被列入僅的第一個IP包分散的消息。但是,這適用於與其他需要與之交談的機器(例如使用recvfrom)進行通信,所以我沒有理由深入並嘗試改變它。

但是,我的問題是在閱讀郵件。該框似乎希望碎片udp數據報以相同的方式發送給它。我的意思是它期望每個ipv4片段都有一個udp頭。在試圖改變它(這是一個相當專業和複雜的平臺)之前,我想知道是否有任何方法來配置sendto()或其他任何用於以這種格式發送udp消息的函數。我在監視那些udp頭部不存在的流量時看到。

非常感謝您的幫助。

+0

我有一個很難相信這一點。你可以附加一個展現這種行爲的Wireshark轉儲嗎? – EJP 2015-02-07 08:39:14

+0

我同意@EJP。在你的例子中,ip hdr是否設置了M標誌? FO是否非零? – 2015-04-02 17:10:29

回答

1

編號套接字不能這樣工作。只需編寫您自己的sendto包裝器,即可根據您選擇的任何緩衝區大小邊界將幀跨越多個UDP數據包進行手動分段。這將達到你想要的效果。

示例代碼如下:

ssize_t fragmented_sendto(int sockfd, const void *buf, size_t len, int flags, 
      const struct sockaddr *dest_addr, socklen_t addrlen, size_t MAX_PACKET_SIZE) 
{ 
    unsigned char* ptr = (unsigned char*) buf; 

    size_t total = 0; 

    while (total <= len) 
    { 
     size_t newsize = len - total; 
     if (newsize > MAX_PACKET_SIZE) 
     { 
      newsize = MAX_PACKET_SIZE; 
     } 
     ssize_t result = sendto(sockfd, ptr, newsize, flags, dest_addr, addrlen); 
     if (result < 0) 
     { 
      // handle error 
      return -1; 
     } 
     else 
     { 
      total += result; 
      ptr += result; 
     } 
    } 
    return (ssize_t)total; 
} 
+0

這聽起來像OP的系統已經在做你正在這裏建議的。該解決方案將生成一組IP數據包,每個數據包都帶有一個UDP標頭。它不能解決OP無法處理實際的IP分片數據包的問題。 – 2015-04-02 17:08:03

相關問題