1. 程式人生 > >Linux: fd_set用法

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集合中*/

    過去,一個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位

置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的最大值必須<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