2012-04-25 21 views
6

我有一個應用程序,通過可以單工(單向傳輸)或雙工模式(雙向)操作的鏈路,從發送端發送數據到接收端。在單工模式下,應用程序使用UDP發送數據,而在雙工模式下,它使用TCP。由於TCP套接字上的寫入可能會被阻塞,因此我們使用非阻塞IO(ioctl與FIONBIO - O_NONBLOCK和fcntl在此分發版上不受支持)以及select()系統調用來確定何時可以寫入數據。 NIO被使用,以便在網絡狀況惡化的情況下,如果需要,我們可以在超時之後提前中止發送。我想使用相同的基本代碼來進行發送,而是在更高的抽象之間改變TCP/UDP。這對TCP很有用。非阻塞UDP寫入返回的字節數是否少於請求的字節數?

但是我很關心Non Blocking IO如何適用於UDP套接字。我可能會錯誤地閱讀手冊頁,但是由於write()可能會返回表示發送的字節數少於請求的字節數,這是否意味着客戶端在其數據報中將收到更少的字節?要發送給定的數據緩衝區,可能需要多次寫入,這可能是因爲我使用非阻塞IO。我擔心這會轉化爲客戶端收到的多個UDP數據報。

我對套接字編程相當陌生,所以請原諒我,如果在這裏有一些誤解。謝謝。

+0

您可能想要檢查您正在使用的任何系統的詳細信息;你的UDP棧可能有特定的限制(事實上,正如你已經說過的那樣)。 – geekosaur 2012-04-25 05:05:35

回答

2

假設一個正確的(沒有損壞的)UDP實現,那麼每個send/sendmsg/sendto將對應於發送的完整數據報,並且每個recv/recvmsg/recvfrom將恰好對應於接收的整個數據報。

如果UDP消息無法完整傳輸,則應收到EMSGSIZE錯誤。發送的消息可能由於網絡中某個點的大小而仍然失敗,在這種情況下,它不會到達。但它不會被分割(除非IP堆棧是嚴重錯誤的)。

一個好的經驗法則是保持您的UDP有效負載大小最多1400字節。這非常接近,爲各種形式的隧道留下了很多空間,以避免碎片。

+0

謝謝。我做了一些更多的測試,發現無論是我的整個有效負載還是沒有發送給一個給定的write()調用UDP - 這真的是唯一合乎邏輯的事情發生。我在VxWorks 5.5上使用供應商提供的堆棧來支持TOE ...我並不感到驚訝,我沒有在目標平臺上看到EMSGSIZE。無論如何,感謝權威的迴應,這絕對有助於提供我已經涵蓋基地的信心。 – aig7761 2012-04-27 15:11:53