2014-09-24 42 views
2

給定客戶端FD列表(例如:98,99,100),同時在FD 99,100上接收數據 選擇取消阻止並讀取FD包含FD:99和FD:100c-select()標識第一個未阻止的fd選擇讀取/ recv操作

如何確定,哪個數據是第一個FD在哪?

如果我連續檢查我的數組中是否有客戶端FD的列表,它將總是嘗試在FD上執行套接字讀取:99.但是,我的應用程序必須從FD:100讀取數據, FD先。

FD_ZERO(&readfds); 
FD_SET(98, &readfds); 
FD_SET(99, &readfds); 
FD_SET(100, &readfds); 
gMaxfd=100; 
rc = select(gMaxfd+1, &readfds, NULL, NULL, NULL); 
if(rc>0){ 
    /* Handle the fds for read operation */ 
    /* Here how to identify which is the first FD on which recv has to be called first ???*/ 
} 
+0

您是否考慮使用[poll(2)](http://man7.org/linux/man-pages/man2/poll.2.html),它比'select'(google for * C10K問題* );爲什麼你關心哪個fd有最舊的數據? – 2014-09-24 11:50:44

+0

你應該解釋更多關於你的應用程序在做什麼,以及你想要什麼樣的應用程序級協議(什麼樣的消息和交換)。 – 2014-09-28 12:05:02

回答

0

您想實施一些round-robin調度。因此請使用poll(2)並記住以前處理的文件描述符。順便說一句,作爲answered by Wumpus您的多路複用系統調用(pollselect ...)通常會提供一個(或幾個)可讀文件描述符。

可替換地,重新啓動event loop

注意,UDP和TCP都是面向字節,沒有消息分組(在應用程序級)中的任何概念之前,從所有可讀文件描述符讀取。見ip(7)udp(7)tcp(7)Internet Protocol Suite,記住TCP僅僅是一個字節流而不任何分組或消息邊界在應用程序級:在一端具有給定的單個send(2)可以在得到通幾個recv(2)另一側(反之亦然,幾個send可以合併成一個recv等等......)。您的應用程序必須緩衝區和您的協議必須定義消息界限。發射器和接收器之間的路由器被允許 - 並且隨意組合和加入數據「數據包」!

+0

如果協議可以在UDP或TCP套接字上接收數據,那麼如何建立首先接收哪個FD數據的協作關係?例如:數據包1,通過UDP接收,FD:99,選擇解除阻止 ,立即多兩個數據包, 數據包2,通過TCP接收,FD:100和 數據包3,通過UDP接收FD:99 在這種情況下,應用程序或協議分析器必須從FD 100讀取數據,因爲它先來了,如果我做了seqential搜索,我將以LIFO而不是FIFO結束。 請提出在不知道先前收到哪些數據的FD的情況下如何進行重新設計或進行哪種重新設計? – 2014-09-24 21:55:59

+0

你的協議然後設計得很差。每封郵件都包含一些唯一的ID。 – 2014-09-25 05:02:54

+0

您應該更多地解釋您正在使用的應用程序協議。我猜這是非常錯誤的。 – 2014-09-25 05:13:02

1

如果在使這些文件描述符可讀的事件之間有任何顯着的延遲,那麼select將與第一個一起返回而不等待第二個。所以如果你有多個fds,你應該把這些事件同時處理。

如果來自不同來源的同時發送的消息破壞了更高級別的協議,則需要重新設計它。

+0

如果協議可以接收UDP或TCP套接字上的數據,那麼如何使先前接收哪個FD數據的關聯成爲可能?例如:數據包1,通過UDP接收,FD:99,選擇解除阻止 ,立即多兩個數據包, 數據包2,通過TCP接收,FD:100和 數據包3,通過UDP接收FD:99 在這種情況下,應用程序或協議分析器必須從FD 100讀取數據,因爲它先來了,如果我做了seqential搜索,我將以LIFO而不是FIFO結束。 請提出在不知道先前收到哪些數據的FD的情況下如何進行重新設計或進行哪種重新設計? – 2014-09-24 21:44:01