2011-08-10 49 views
6

我訪問過很多網站和教程(和文檔),但我仍然有一個問題沒有答案。如果UDP數據包到達,當我不在運行socket.receive(...)時會發生什麼?它會以某種方式緩衝,直到我調用socket.receive(...)或完全丟失?如果我沒有從DatagramSocket主動接收數據包,是否會丟包?

也是Android的DatagramSocket實現線程安全的意思,你可以寫入套接字時,聽它,或不?

回答

9

內核網絡堆棧爲每個插槽保留一個接收緩衝區。您可以通過調用setsockopt(2)系統調用SO_RCVBUF選項來控制它的大小(您必須弄清楚它的Java API是什麼)。

因此,只要該緩衝區中有足夠的空間,傳入的數據包就會在內核中排隊。它是而不是是應用程序在該特定時刻執行「接收」功能所需的。如果應用程序沒有足夠快地將數據包排隊(即讀取),則緩衝區溢出並且內核開始丟棄數據包。在Linux(通常是Unix)上,您應該能夠使用netstat -s命令查看數據包丟棄計數。

讓我也注意到,這個緩衝區不是唯一可以丟棄數據包的地方。如果NIC上的內存空間不足,硬件可能會丟棄數據包。然後,如果內核太忙且不處理其通用網絡輸入隊列,設備驅動程序可能丟棄數據包。儘管如此,你仍然需要嚴肅的消息。

TCP試圖通過總排序和必要時重傳來解決所有這些問題。 UDP只是簡單的「發送和忘記」,不會爲丟棄的數據包做任何事情(除非在連接UDP套接字的第二個send(2)出現錯誤並且只有在ICMP工作正常的情況下)。

底線是數據包被緩衝,但達到該點,然後丟棄。

+1

榮譽給你!檢查了Android文檔,默認套接字緩衝區大小爲4098字節。這使套接字概念更清晰。 – LordTwaroog

相關問題