參考《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個套接字都加入到感興趣的集合中;並且有事件發生的時候,要檢查所有套接字是否 在各個集合中,會影響服務程序運行的效率。