2012-01-05 60 views
3

美好的一天,UDP recv/recvfrom多個發件人

我正在開發一個在VC++中使用UDP協議與Windows XP上的winsock進行通信的應用程序。以前我可以假定工具接收的所有數據包來自單個目標。不過,我現在正在做廣播接收。監聽線程具有最小的開銷,應該把它所有的時間對下面一行:

rv = recvfrom(socket, 
       p_buffer_p, 
       p_size, 
       0, 
       (sockaddr*)&clientService_in, //This is set to do a broadcast recv 
       &SenderAddrSize); 

我的問題是我是否可以認爲,我從recvfrom的一個回報得到一個緩衝是從一個單一的目標。也就是說,1個調用發送的應用程序發送的應用程序等於從recvfrom返回接收應用程序?或者多個發送者的多個發送可以一起發送到1?

我假設來自目標的單個發送無法從recvfrom分裂爲多個返回。無論如何,我一直認爲這個問題並沒有問題。

還有一件事,它是一個SOCK_DGRAM類型的套接字。

回答

6

不,不能拆分UDP消息。他們是在他們被派往時到達的。另外,多個UDP消息不會連接在一起。

因此,N個sendto消息對應於N個recvfrom調用。從wiki

報價:

數據報 - 數據包單獨發送,並檢查,只有當他們到達 完整性。數據包具有明確的界限,在接收到數據包之後 將被兌現,這意味着在接收器處的讀取操作將會產生完整的消息,如其最初發送的那樣。

+0

好的,謝謝。我讀過其他地方發佈的一些東西,似乎表明它們可能會分裂並變得鬆軟,但我想這是針對不同的協議。我不熟悉winsock中連接之間的差異。 – Ian 2012-01-05 20:08:13

+0

@Ian該協議可能是基於流的協議(TCP/SCTP) – INS 2012-01-05 20:10:53

2

你是正確的,一個單一的通話給recvfrom()將最多一個UDP數據包返回。 但是不能保證每個數據報都會真正到達。

特別是,如果您發送的UDP數據報過大,它可能會在網絡級別分裂成碎片(碎片),從而增加數據報被丟棄的可能性(因爲任何碎片的丟失都會導致整體損失)。您在應用程序級別看不到碎片,因爲網絡級別會爲您重新組裝數據包。

事情會變得非常棘手,因爲事先不可能知道究竟有多大,有各種算法可供查找,但它們都屬於試驗和錯誤。更糟的是,防火牆,路由器和操作系統可以(並且經常)隨着時間的推移改變其對碎片數據報的行爲。可能會出現這樣的情況,即特定大小或組合的數據包總是會被丟棄,因爲它違反了某些防火牆規則。因此,不要假設sendto()必然會導致recvfrom(),並嘗試保持數據報的小(小於1400字節相當安全,小於512字節非常安全)。

相關問題