windows socket----select模型
一般我們的網絡編程都是用bind ,listen,accept,send/sendto,recv/recvfrom。在創建套接字的時候,是默認使用阻塞模式的,每當我們調用send/sendto等方法時,套接字都會進入阻塞狀態,等到條件滿足后才返回。當然為每個連接創建線程是個解決這個問題的好辦法。如:比較容易想到的一種服務器模型就是采用一個主線程,負責監聽客戶端的連接請求,當接收到某個客戶端的連接請求后,創建一個專門用于和該客戶端通信的套接字和一個輔助線程。以后該客戶端和服務器的交互都在這個輔助線程內完成。這種方法比較直觀,程序非常簡單而且可移植性好,但是不能利用平臺相關的特性。例如,如果連接數增多的時候(成千上萬的連接),那么線程數成倍增長,操作系統忙于頻繁的線程間切換,而且大部分線程在其生命周期內都是處于非活動狀態的,這大大浪費了系統的資源。
我們也可以通過ioctlsocket方法使用非阻塞模式套接字,但是這對程序員的代碼量是個考驗。
?
Select(選擇)模型是Winsock中最常見的I/O模型。也是解決這二者問題的方案,和前兩者比較有很大的進步。并且不會改變套接字的工作模式。
int select (int nfds, fd_set FAR * readfds, fd_set FAR * writefds, fd_set FAR * exceptfds, const struct timeval FAR * timeout );?該函數返回處于就緒態并且已經被包含在fd_set結構中的套接字總數。如果超時則返回0。
????第一個參數nfds被忽略。
????第二個參數readfds,可讀性套接字集合指針。
????第三個參數writefds,可寫性套接字集合指針。
????第四個參數exceptfds,檢查錯誤套接字集合指針。
????第五個參數timeout,等待時間。
readfds,writefds,exceptfds三個參數至少有一個不為NULL。
typedef struct fd_set {u_int fd_count; /* how many are SET? */SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */ } fd_set;?
fd_set是一個SOCKET隊列,以下宏可以對該隊列進行操作:
FD_CLR( s, *set) 從隊列set刪除句柄s;
FD_ISSET( s, *set) 檢查句柄s是否存在與隊列set中;
FD_SET( s, *set )把句柄s添加到隊列set中;
FD_ZERO( *set ) 把set隊列初始化成空隊列.
Select模型工作流程:當把我們要監控的那些套接字根據各自的操作放入到readfds,writefds,exceptfds中,當select方法返回后,我們通過判斷是否套接字還在那個readfds中,如果在,說明有數據可以讀,調用recv方法讀數據。其他集合一樣。以監聽套接字為例:Select()--------->FD_ISSET(listenSocket,&readSet)------->acceptSocket=accept(listenSocket,(sockaddr*)&addr,&len); ?此時在調用accept就不會阻塞了。
?
轉載于:https://www.cnblogs.com/pangblog/p/3310449.html
總結
以上是生活随笔為你收集整理的windows socket----select模型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jTessBoxEditor for T
- 下一篇: TortoiseGit for wind