socket網路編程之select模型
來源:互聯網
上載者:User
select函數原型: int select (int maxfdp1,fd_set *readset,fd_set *writeset, fd_set *exceptset,const struct timeval * timeout); 參數解釋: 參數1:最大的檔案描述符加1。 參數2:用於檢查可讀性, 參數3:用於檢查可寫性, 參數4:用於檢測帶外資料, 參數五:一個指向timeval結構的指標,用於決定select等待I/o的最長時間。如果為空白將一直等待。如果值設定為{0,0},表明select會立即返回。 timeval結構的定義: struct timeval { long tv_sec; // seconds long tv_usec; // microseconds } 傳回值解釋: >0:就緒描述字的正數目 -1:出錯 0 :逾時 select相關宏: ● FD_CLR(s, *set):從set中刪除通訊端s。
● FD_ISSET(s, *set):檢查s是否set集合的一名成員;如答案是肯定的是,則返回TRUE。
● FD_SET(s, *set):將通訊端s加入集合set。
● FD_ZERO( * set):將set初始化成空集合。 使用步驟: 假定我們想知道是否可從一個通訊端中安全地讀取資料,同時不會陷於無休止的
“鎖定”狀態,便可使用 FDSET 宏,將自己的通訊端分配給 fdread 集合,再來調用 select。要
想檢測自己的通訊端是否仍屬 fdread 集合的一部分,可使用 FD_ISSET 宏。採用下述步驟,便
可完成用 select 操作一個或多個通訊端控制代碼的全過程:
1) 使用FDZERO宏,初始化一個fdset對象;
2) 使用FDSET宏,將通訊端控制代碼加入到fdset集合中;
3) 調用 select 函數,等待其返回……select 完成後,會返回在所有 fdset 集合中設定的通訊端控制代碼總數,
並對每個集合進行相應的更新。
4) 根據 select的傳回值和 FDISSET宏,對 fdset 集合進行檢查。
5) 知道了每個集合中“待決”的 I/O操作之後,對 I/O進行處理,
然後返回步驟1 ),繼續進行 select 處理。 select 函數返回後,會修改 fdset 結構,刪除那些不存在待決 I/O 操作的通訊端控制代碼。
這正是我們在上述的步驟 ( 4 ) 中,為何要使用 FDISSET 宏來判斷一個特定的通訊端是否仍在集合中的原因。
fd_set結構體解釋: struct fd_set可以理解為一個集合,這個集合中存放的是檔案描述符(filedescriptor),即檔案控制代碼,這可以是我們所說的普通意義的檔案, 當然Unix下任何裝置、管道、FIFO等都是檔案形式,全部包括在內,所以毫無疑問一個socket就是一個檔案,socket控制代碼就是一個檔案描述符。