Linux: fd_set用法
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通常只能包含<32的fd(檔案描述字),因為fd_set其實只用了一個32位向量來表示fd; 現在,UNIX系統通常會在標頭檔案<sys/select.h>中定義常量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位
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的最大值必須<FD_SETSIZE。
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函式才返回)
2. timeout所指向的結構設為非零時間(等待固定時間:有一個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)
{
int rc;
fd_set fds;
struct timeval tv;
FD_ZERO(&fds);
FD_SET(fd, &fds);
tv.tv_sec = tv.tv_usec = 0;
rc = select(fd+1, &fds, NULL, NULL, &tv);
if( rc<0 ) //error
return -1;
return FD_ISSET(fd, &fds) ? 1: 0;
}
下面還有一個複雜一些的應用:
//這段程式碼將指定測試Socket的描述字的可讀可寫性,因為Socket使用的也是fd
unit32 SocketWait(TSocket* s, bool rd, bool wr, unit32 timems)
{
fd_set rfds, wfds;
#ifdef _WIN32
TIMEVAL tv;
#else
struct timeval tv;
#endif /*_WIN32*/
FD_ZERO(&rfds);
FD_ZERO(&wfds);
if(rd) //TRUE
FD_SET(*s, &rfds); //新增要測試的描述字
if(wr)
FD_SET(*s, &wfds);
tv.tv_sec = timems/1000; //seconds
tv.tv_usec = timems%1000; //ms
for(;;) //如果errno==EINTR,反覆測試緩衝區的可讀性
switch(select((*s)+1, &fds, &wfds, NULL, (timems==TIME_INFINITE?NULL:&tv))) //測試在規定的時間內套接字介面接收緩衝區是否有資料可讀
{
// 0——超時, -1——出錯
case 0: /*time out*/
return 0;
case (-1): /*socket error*/
if( SocketError()==EINTR )
break;
return 0; //有錯但不是EINTR
default:
if(FD_ISSET(*s, &rfds)) //如果s是fds中的一員返回非0,否則返回0
return 1;
if(FD_ISSET(*s, &wfds))
rerun 2;
return 0;
};
}
相關推薦
Linux: fd_set用法
select()機制中提供一fd_set的資料結構,實際上是一long型別的陣列,每一個數組元素都能與一開啟的檔案控制代碼(不管是socket控制代碼,還是其他檔案或命名管道或裝置控制代碼)建立聯絡,建立聯絡的工作由程式設計師完成,當呼叫select()時,由核心根據IO狀態修改fe_set的內容,由此
【轉】shell expect spawn、linux expect 用法小記 看著舒服點
ssh username 英文 認識 exe 無法找到 usr 過去 操作 使用expect實現自動登錄的腳本,網上有很多,可是都沒有一個明白的說明,初學者一般都是照抄、收藏。可是為什麽要這麽寫卻不知其然。本文用一個最短的例子說明腳本的原理。 腳本代碼如下: #####
linux expr用法
反引號 bstr 說明 字符串 -s sar 空格 nbsp numeric expr命令是一個手工命令行計數器,用於在UNIX/LINUX下求表達式變量的值,一般用於整數值,也可用於字符串。–格式為:expr Expression(命令讀入Expression 參數,計算
linux tail用法
運行 默認 偏移 用法 例子 可能 ber 讀取 導致 一.tail命令的用法 tail [ -f ] [ -c Number | -n Number | -m Number | -b Number | -k Number ] [ File ]參數解釋:-f 該參數用於監
Linux find用法
house min command 工作目錄 find用法 而且 use 我想 結果 Linux中find常見用法示例 ----摘抄哪裏忘記了 ·find path -option [ -print ] [ -exec -ok command ]
Linux AWK用法
科學 if語句 nts 逗號 分開 意思 ons 名稱 沒有 AWKawk:報告生成器,格式化文本輸出gawk:模式掃描和處理語言 基本語法: options:選項 program:awk的語言 var=value:賦值給var
linux chattr用法
第一次 權限 很多 隱藏 如果 -c nbsp 選項 att 在linux中,我們有的時候發現linux無法刪除一個文件或者目錄。 huskiesir第一次遇見這個問題還是在一次服務器被不法分子入侵之後的事情,我就發現某個進程很多,根據進程的名字,我搜索關鍵字找到了
Linux-fgets用法
原型 char *fgets(char *s, int size, FILE *stream); s:儲存內容地址 size:最大輸入可儲存數量 使用
linux—find用法詳解
linux 中find 常用示例解析 find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path…] [expression] 其實[-H] [-L] [-P] [-D debugopts] [-Olevel]這幾
Linux nmon用法
Linux安裝與使用nmon 監控、分析系統性能 安裝:yum –y install nmon 執行:nmon 我們執行相關的命令,就會出現相關的資訊了,比如這裡我按c,就會顯示cpu的相關資訊,接下來我們緊接著按鍵盤m
fd_set 用法 socket
一、winsock中 #include <winsock.h> 原型 int select( int nfds , fd_set* , fd_set* , fd_set* , const struct timeval* );
fd_set 用法
select()函式主要是建立在fd_set型別的基礎上的。fd_set(它比較重要所以先介紹一下)是一組檔案描述字(fd)的集合,它用一位來表示一個fd(下面會仔細介紹),對於fd_set型別通過下面四個巨集來操作: fd_set set; FD_ZERO(&se
linux--PS用法
在linux中使用ps命令可以檢視有哪些程序在執行和執行的狀態、程序是否結束、程序有沒有殭屍、哪些程序佔用了過多的資源等等. ps命令最常用的是用於監控後臺程序的工作情況 1、ps -aux 顯示所有包含其他使用者的行程 USER: 行程擁有者 PID: pid %CPU: 佔用的 C
shell expect spawn、linux expect 用法小記 看著舒服點
使用expect實現自動登入的指令碼,網上有很多,可是都沒有一個明白的說明,初學者一般都是照抄、收藏。可是為什麼要這麼寫卻不知其然。本文用一個最短的例子說明指令碼的原理。 指令碼程式碼如下: #####################################
linux find 用法和常見用例
-nogroup #查無有效屬組的檔案,即檔案的屬組在/etc/groups中不存在-nouser #查無有效屬主的檔案,即檔案的屬主在/etc/passwd中不存-newer f1 !f2 找檔案,
linux--sed用法
sed是一個很好的檔案處理工具,本身是一個管道命令,主要是以行為單位進行處理,可以將資料行進行替換、刪除、新增、選取等特定工作,下面先了解一下sed的用法 sed命令列格式為: sed[-nefri] ‘command’ 輸入文字 常用選項:-n∶使用安靜
Linux命令用法總結二
1、使用遠端連線工具CRT ifconfig 檢視Linux IP地址 ifconfig 網絡卡名稱 檢視指定網絡卡的資訊 ifconfig -a
linux CONFIG_DEBUG_OBJECTS 用法
該選項用來開啟debugobjects模組,對應核心程式碼中的debugobjects.c, 這個模組是個通用的除錯框架,用來跟蹤object的生命週期。 kernel中已有的應用該功能的object有timer,workqueue等, 當然自己也可以定義自己的模組使用這個
linux grep用法大全
原文:http://orchidllh.itpub.net/post/4020/24280 在Unix中經常會用到grep去選取所需要的資訊,用好grep有時可以到達意想不到的效果。 Grep : g (globally) search for a re (r
Linux幫助用法總結
發行版 一行 thead text 翻屏 工具 linux內核 依次 功能性 Linux幫助用法總結 獲取幫助的能力決定了Linux水平的高低!我們既可以用linux本身自帶的強大幫助功能,也可以去軟件和系統發行版的官網上獲取官方資料。學會使用幫助命令可以大大減輕你學lin