select()機制中提供一fd_set的資料結構,實際上是一long型別的陣列,每乙個陣列元素都能與一開啟的檔案控制代碼(不管是socket控制代碼,還是其他檔案或命名管道或裝置控制代碼)建立聯絡,建立聯絡的工作由程式設計師完成,當呼叫select()時,由核心根據io狀態修改fe_set的內容,由此來通知執行了select()的程序哪一socket或檔案可讀。
多埠復用函式select在呼叫前要首先設定監聽的埠數目,fd_zero是清空埠集,fd_set是設定埠集。
select()函式常常用在用乙個程序監聽多個伺服器端socket。
有時,select()也被當作延時函式使用。sleep()延時會釋放cpu,select()的話,可以在占用cpu的情況下延時。
select()函式主要是建立在fd_set型別的基礎上的。fd_set(它比較重要所以先介紹一下)是一組檔案描述字(fd)的集合,它用一位來表示乙個fd(下面會仔細介紹),對於fd_set型別通過下面四個巨集來操作:
fd_set set;
fd_zero(&set); /*將set清零使集合中不含任何fd*/
fd_set(fd, &set); /*將fd加入set集合*/
fd_clr(fd, &set); /*將fd從set集合中清除*/
fd_isset(fd, &set); /*測試fd是否在set集合中*/
過去,乙個fd_set通常只能包含<32的fd(檔案描述字),因為fd_set其實只用了乙個32位向量來表示fd; 現在,unix系統通常會在標頭檔案中定義常量fd_setsize,它是資料型別fd_set的描述字數量,其值通常是1024,這樣就能表示<1024的fd。根據fd_set的位向量實現,我們可以重新理解操作fd_set的四個巨集:
fd_set set;
fd_zero(&set); /*將set的所有位置0,如set在記憶體中佔8位則將set置為00000000*/
fd_set(0, &set); /*將set的第0位置1,如set原來是00000000,則現在變為100000000,這樣fd==1的檔案描述字就被加進set中了*/
fd_clr(4, &set); /*將set的第4位置0,如set原來是10001000,則現在變為10000000,這樣fd==4的檔案描述字就被從set中清除了*/
fd_isset(5, &set); /*測試set的第5位是否為1,如果原來set是10000100,則返回非零,表明fd==5的檔案描述符在set中,否則返回0*/
注意:fd的最大值必須
select函式的介面比較簡單:
int select(int nfds, fd_set* readset, fd_set* writeset, fe_set* exceptset, struct timeval* timeout);
功能:測試指定的fd可讀?可寫?有異常條件待處理?
引數:nfds: 需要檢查的檔案描述字個數(即檢查到fd_set的第幾位),數值應該比三組fd_set中所含的最大fd值更大,一般設為三組fd_set中所含的最大fd值加1(如在readset, writeset, exceptset中所含最大的fd為5,則nfds=6,因為fd是從0開始的 )。設這個值是為了提高效率,使函式不必檢查fd_set的所有1024位。
readset: 用來檢查可讀性的一組檔案描述字。
writeset: 用來檢查可寫性的一組檔案描述字。
exceptset: 用來檢查是否有異常條件出現的檔案描述字。(注:錯誤不包括在異常條件之內)
timeout: 有三種可能:
1. timeout = null (阻塞:直到有乙個fd位被置為1函式才返回)
3. timeout所指向的結構,時間設為0(非阻塞:函式檢查完每乙個fd後立即返回)
返回值:返回對應位仍然為1的fd的總數。
remark:
三組fd_set均將某些fd位置0,只有那些可讀,可寫以及有異常條件待處理的fd位仍然為1。
使用select函式的過程一般是:
先呼叫巨集fd_zero將指定的fd_set清零,然後呼叫巨集fd_set將需要測試的fd加入fd_set,接著呼叫函式select測試fd_set中的所有fd,最後用巨集fd_isset檢查某個fd在函式select呼叫後,相應位是否仍然為1。
以下是乙個測試單個檔案描述字可讀性的例子:
int isready(int fd)
下面還有乙個複雜一些的應用:
//這段**將指定測試socket的描述字的可讀可寫性,因為socket使用的也是fd
unit32 socketwait(tsocket* s, bool rd, bool wr, unit32 timems);}
轉至:
windows網路程式設計 select模型
select模型與一般模型的區別是selete模型使用fd set資料型別和select函式在核心裡維護一張存有連線上的socket表,使用select輪循處理這些socket,實現同時與多個socket連線。基本工作原理 建立socket,繫結,監聽,開個死迴圈,當發現有socket請求連線後把該...
網路程式設計基礎 使用SELECT模型
tcp 使用select 服務端 code author lin yiqian created 2009 09 17 describe tcp select 服務端 include include include pragma comment lib,ws2 32.lib typedef std s...
windows網路程式設計之Select模型基礎知識
網路程式設計之select模型 一.設計思想 利用select函式,判斷套接字上是否存在資料,或者能否向乙個套接字寫入資料。目的是防止應用程式在套接字處於鎖定模式時,呼叫recv 或send 從沒有資料的套接字上接收資料,被迫進入阻塞狀態。二.select函式 2.1 select函式 int se...