日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

fd_set 用法

發布時間:2025/3/15 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 fd_set 用法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://www.cnblogs.com/wolflion/archive/2011/07/13/2539137.html

select()函數主要是建立在fd_set類型的基礎上的。fd_set(它比較重要所以先介紹一下)是一組文件描述字(fd)的集合,它用一位來表示一個fd(下面會仔細介紹),對于fd_set類型通過下面四個宏來操作:?

fd_set set;

FD_ZERO(&set);??????

FD_SET(fd, &set);???

FD_CLR(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);?????

FD_SET(0, &set);???

FD_CLR(4, &set);?????

FD_ISSET(5, &set);???

―――――――――――――――――――――――――――――――――――――――

注意fd的最大值必須<FD_SETSIZE。

―――――――――――――――――――――――――――――――――――――――?

select函數的接口比較簡單:

int select(int nfds, fd_set *readset, fd_set *writeset,

fd_set* exceptset, struct tim *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的總數。?

Remarks:

三組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 tim 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

uint32 SocketWait(TSocket *s,bool rd,bool wr,uint32 timems)????

{

?????fd_set rfds,wfds;

?#ifdef _WIN32

?????TIM tv;

?#else

?????struct tim tv;

?#endif????

?????FD_ZERO(&rfds);

?????FD_ZERO(&wfds);?

?????if (rd)???//TRUE

?????FD_SET(*s,&rfds);???//添加要測試的描述字?

?????if (wr)?????//FALSE

???????FD_SET(*s,&wfds);?

?????tv.tv_sec=timems/1000;?????//second

?????tv.tv_usec=timems00;?????//ms?

?????for (;;) //如果errno==EINTR,反復測試緩沖區的可讀性

??????????switch(select((*s)+1,&rfds,&wfds,NULL,

??????????????(timems==TIME_INFINITE?NULL:&tv)))??//測試在規定的時間內套接口接收緩沖區中是否有數據可讀

?????????{ ?????????????????????????????????????????????//0--超時,-1--出錯

?????????case 0:????

??????????????return 0;?

?????????case (-1):???

??????????????if (SocketError()==EINTR)

???????????????????break;??????????????

??????????????return 0; //有錯但不是EINTR?

??????????default:

??????????????if (FD_ISSET(*s,&rfds)) //如果s是fds中的一員返回非0,否則返回0

???????????????????return 1;

??????????????if (FD_ISSET(*s,&wfds))

???????????????????return 2;

??????????????return 0;

?????????};

?

}

轉載于:https://www.cnblogs.com/johnnyflute/p/3800984.html

總結

以上是生活随笔為你收集整理的fd_set 用法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。