參考《windows網路編程》第五章。為鞏固知識,以問題作為驅動,檢查知識點。
windows下 Select模型
1. Select模型有什麼作用?
可以判斷指定通訊端上是否有資料存在、是否可以寫入資料。防止因為使用send或recv過程引起的阻塞狀態。
2. Select模型有什麼優點?
可以減少原有阻塞模型需要使用的多個線程,減少資源消耗。
3. Select函數原型是什嗎?
Int select(
Int nfds,//忽略不用
Fd_set FAR *readfds,
Fd_set FAR *writefds,
Fd_set FAR *exceptfds,
Const struct timeval FAR * timeout
);
4. Readfds集合的條件是什嗎?
Readfds檢查可讀性,當以下任一條件成立時,對應的socket會保留在select返回後的readfds中:
*有資料可以讀入
*串連已經被關閉、重啟或者終止
*如果已經調用了listen,而且有一個串連正在等待建立,即將在accept返回成功
5. Writefds集合的條件是什嗎?
Writefds檢查可寫性,當以下任一條件成立時,對應的socket會保留在select返回後的Writefds中:
*有資料可以發送
*如果一個非阻塞串連請求正在被處理,並且串連已經成功
6. Exceptfds集合的條件是什嗎?
Exceptfds檢查例外socket狀態,Exceptfds當以下任一條件成立時,對應的socket會保留在select返回後的exceptfds中:
*如果一個非阻塞串連請求正在被處理,並且串連嘗試失敗
*有OOB(out of band)資料可供讀取
7. 怎麼測試一個通訊端是否可讀?
將通訊端s加入到readfds集合中,然後調用select函數等待完成;當select完成之後,判斷通訊端s是否仍在readfds集合中;如果是則表明有資料可讀,可立即著手從上面讀取資料。如果不在集合中則沒有可讀資料。
8. 三個集合中可以同時為空白嗎?
不可以,必須有一個或以上集合為非空,select才能等待。
9. Select會阻塞嗎?哪個參數條件決定?
在所有三個集合中的條件都沒有發生的情況下會阻塞;阻塞多少時間由timeval參數決定。如果timeout指標為空白,則會一直阻塞直到三個集合中有條件成立。
10. 如果timeval設定為0,會出現什麼情況?
如果timeval設定為0,select操作在檢查了三個集合中的狀態後立即返回,允許程式對select操作進行輪詢。但出於效能考慮,應避免這樣的設定。
11. 對集合的操作宏有四個,分別是什嗎?
FD_ZERO(*set) 將集合s初始化為空白集
FD_CLR(s,*set) 從set中刪除通訊端
FD_ISSET(s,*set) 檢查s是否在set集合中
FD_SET(s,*set) 將通訊端s加入集合s中
12. Select操作一個或多個通訊端控制代碼的過程是怎麼樣的?
*用 FD_ZERO初始化自己感興趣的fd_set
*用FD_SET將通訊端分配給需要使用的fd_set
*調用select函數,並設定逾時時間長度
*select函數傳回值表示已經等待成功的socket的資料,並且返回時,對應的fd_set只剩下有對應條件發生的通訊端集合;使用FD_ISSET對集合是否包含通訊端做檢查
*對每個集合中有對應事件發生的通訊端做資料處理
*重新回到第一步,初始化fd_set
13. Fd_set結構有什麼限制?怎麼突破這個限制?
Fd_set結構的大小FD_SETSIZE在winsock2.h中定義只能放64個通訊端。如果要加大這個值,在包含winsock2.h之前將FD_SETSIZE定義為自己希望的大小。
14. 對於比較多的通訊端,select有什麼劣勢?
Select模型使用三個集合來檢查是否有某些條件成立,就意味著如果有1000個通訊端,就需要在調用select之前使用FD_SET把這1000個通訊端都加入到感興趣的集合中;並且有事件發生的時候,要檢查所有通訊端是否 在各個集合中,會影響服務程式啟動並執行效率。