2012-11-24 42 views
1

我正在寫一個UDP服務器/客戶端程序,服務器通過一個固定窗口大小的單個端口向客戶端發送數據包,並且客戶端將爲每個收到的數據包發回ack數據包。現在我想讓服務器處理丟包的情況。通過一些谷歌搜索,似乎我應該使用ALARMSELECT。我當然不希望發送一個數據包,等待確認或超時,然後發送另一個數據包,但SELECT會在超時期間阻塞調用功能,所以我認爲它不好。 ALARM也不好,因爲一個程序只能有一個ALARM。那麼有沒有什麼辦法可以讓我跟蹤多個數據包服務器發送的超時?如何在C中爲多個UDP數據包設置超時?

+0

由於您擔心丟失數據包,爲什麼不使用TCP?我的理解是,UDP最適合「間距和忘記」的情況,也就是說丟包的一些可以接受的地方*和*排序並不重要。如果丟失任何數據包是不可接受的,並且數據包必須「按順序」接收,則TCP會處理跟蹤,確認,重試和數據包排序。 –

回答

1

以下是我首先想到的。

打開套接字以非阻塞模式進行偵聽。非阻塞是關鍵。如果select表示有東西存在,但事件對齊恰到好處,那麼可能是在別處處理的虛假警報,阻止未到來的事情是麻煩。

對於每個發送的數據包都保留一個按升序超時次序排序的鏈表。

收到回覆後,請從鏈接列表中刪除。

使用select可以等待下一個傳入的數據包,並有合理的超時時間。我傾向於使用最多幾秒鐘,即使看起來更長的時間是合理的以涵蓋任何罕見的「萬一」情況。你在這裏阻塞的是傳入的數據包,但不會超出下次超時。

一旦select返回,如果請求可用,則accept()並處理請求。

在迭代循環處理任何新的超時之前,根據需要調整鏈接列表。

快速網絡搜索在http://www.lowtek.com/sockets/select.html上顯示了更多詳細信息。

+0

accept()不用於UDP。 – EJP

0

select()將阻止recvmsg()塊的相同方式。它是一個暫停的替代品。您也可以使用SO_RCVTIMEO選項來設置讀取超時,如果您的平臺支持,讀取超時更簡單。