struct pollfd

int poll (struct pollfd *fds, size_t nfds , int timeout);

struct pollfd {
int fd;        /* 文件描述符 */
short events; /* 等待的事件 */
short revents; /* 實際發生了的事件 */
};

#include <sys/poll.h> 
int poll(struct pollfd *ufds, unsigned int nfds, int timeout); 
struct pollfd 

int fd; /* 想查詢的文件描述符. */ 
short int events; /* fd 上,我們感興趣的事件*/ 
short int revents; /* Types of events that actually occurred. */ 
};

ufds 指向 struct pollfd 數組 
nfds 指定 pollfd 數組元素的個數,也就是要監測幾個 pollfd

EINTR不是信號 是錯誤號 EINTR 

select產生它有2個原因 被信號打斷還有超時 
看你的select設定了超時 而且在後面判斷使用了ret<=0 這樣因爲超時而產生的返回值=0也被包含在裏面了 所以產生了你看見EINTR的效果



poll()函數:這個函數是某些Unix系統提供的用於執行與select()函數同等功能的函數,下面是這個函數的聲明:

#include <poll.h>

int poll(struct pollfd fds[], nfds_t nfds, int timeout);

參數說明:

fds:是一個struct pollfd結構類型的數組,用於存放需要檢測其狀態的Socket描述符;每當調用這個函數之後,系統不會清空這個數組,操作起來比較方便;特別是對於 socket連接比較多的情況下,在一定程度上可以提高處理的效率;這一點與select()函數不同,調用select()函數之後,select() 函數會清空它所檢測的socket描述符集合,導致每次調用select()之前都必須把socket描述符重新加入到待檢測的集合中;因 此,select()函數適合於只檢測一個socket描述符的情況,而poll()函數適合於大量socket描述符的情況;

nfds:nfds_t類型的參數,用於標記數組fds中的結構體元素的總數量;

timeout:是poll函數調用阻塞的時間,單位:毫秒;

返回值:

>0:數組fds中準備好讀、寫或出錯狀態的那些socket描述符的總數量;

==0:數組fds中沒有任何socket描述符準備好讀、寫,或出錯;此時poll超時,超時時間是timeout毫秒;換句話說,如果所檢測的 socket描述符上沒有任何事件發生的話,那麼poll()函數會阻塞timeout所指定的毫秒時間長度之後返回,如果timeout==0,那麼 poll() 函數立即返回而不阻塞,如果timeout==INFTIM,那麼poll() 函數會一直阻塞下去,直到所檢測的socket描述符上的感興趣的事件發 生是才返回,如果感興趣的事件永遠不發生,那麼poll()就會永遠阻塞下去;

-1:  poll函數調用失敗,同時會自動設置全局變量errno;

如果待檢測的socket描述符爲負值,則對這個描述符的檢測就會被忽略,也就是不會對成員變量events進行檢測,在events上註冊的事件也會被忽略,poll()函數返回的時候,會把成員變量revents設置爲0,表示沒有事件發生;

另外,poll() 函數不會受到socket描述符上的O_NDELAY標記和O_NONBLOCK標記的影響和制約,也就是說,不管socket是阻塞的還是非阻塞 的,poll()函數都不會收到影響;而select()函數則不同,select()函數會受到O_NDELAY標記和O_NONBLOCK標記的影 響,如果socket是阻塞的socket,則調用select()跟不調用select()時的效果是一樣的,socket仍然是阻塞式TCP通訊,相 反,如果socket是非阻塞的socket,那麼調用select()時就可以實現非阻塞式TCP通訊;

所以poll() 函數的功能和返回值的含義與 select() 函數的功能和返回值的含義是完全一樣的,兩者之間的差別就是內部實現方式不一樣,select()函數基本上可以在所有支持文件描述符操作的系統平臺上運 行(如:Linux 、Unix 、Windows、MacOS等),可移植性好,而poll()函數則只有個別的的操作系統提供支持(如:SunOS、Solaris、AIX、HP提供 支持,但是Linux不提供支持),可移植性差;

strust pollfd結構說明:

typedef struct pollfd {
        int fd;                               /* 需要被檢測或選擇的文件描述符*/
        short events;                   /* 對文件描述符fd上感興趣的事件 */
        short revents;                  /* 文件描述符fd上當前實際發生的事件*/
} pollfd_t;

typedef unsigned long   nfds_t;

經常檢測的事件標記: POLLIN/POLLRDNORM(可讀)、POLLOUT/POLLWRNORM(可寫)、POLLERR(出錯)

如果是對一個描述符上的多個事件感興趣的話,可以把這些常量標記之間進行按位或運算就可以了;

比如:對socket描述符fd上的讀、寫、異常事件感興趣,就可以這樣做:struct pollfd  fds;

fds[nIndex].events=POLLIN | POLLOUT | POLLERR;

當 poll()函數返回時,要判斷所檢測的socket描述符上發生的事件,可以這樣做: struct pollfd  fds;

檢測可讀TCP連接請求:

if((fds[nIndex].revents & POLLIN) == POLLIN){//接收數據/調用accept()接收連接請求}

檢測可寫:

if((fds[nIndex].revents & POLLOUT) == POLLOUT){//發送數據}

檢測異常:

if((fds[nIndex].revents & POLLERR) == POLLERR){//異常處理}

發佈了2 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章