標籤:second argv struct 編程 它的 描述符 時間 perror write
一、select函數簡介
select一般用在socket網路編程中,在網路編程的過程中,經常會遇到許多阻塞的函數,網路編程時使用的recv, recvfrom、connect函數都是阻塞的函數,當函數不能成功執行的時候,程式就會一直阻塞在這裡,無法執行下面的代碼。這是就需要用到非阻塞的編程方式,使用 selcet函數就可以實現非阻塞編程。
selcet函數是一個輪循函數,即當迴圈詢問檔案節點,可設定逾時時間,逾時時間到了就跳過代碼繼續往下執行
select(),確定一個或多個套介面的狀態,本函數用於確定一個或多個套介面的狀態,對每一個套介面,調用者可查詢它的可讀性、可寫性及錯誤狀態資訊,用fd_set結構來表示一組等待檢查的套介面,在調用返回時,這個結構存有滿足一定條件的套介面組的子集,並且select()返回滿足條件的套介面的數目。
通常採用select實現多工,也就是說可以同時監聽多個檔案描述符;
下面是select的函數原型:
/* According to POSIX.1-2001 */2 #include <sys/select.h>3 4 int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
下面進行具體的解釋:
第一個參數:int nfds--->是一個整數值,是指集合中所有檔案描述符的範圍,即所有檔案描述符的最大值加1
第二個參數:fd_set *readfds---->用來檢查一組可讀性的檔案描述符。
第三個參數:fd_set *writefds---->用來檢查一組可寫性的檔案描述符。
第四個參數:fd_set *exceptfds---->用來檢查檔案檔案描述符是否異常
第五個參數:sreuct timeval *timeout--->是一個時間結構體,用來設定逾時時間
timeout:最多等待時間,對阻塞操作則為NULL
select函數的傳回值
負值:select錯誤
正值:表示某些檔案可讀或可寫
0:等待逾時,沒有可讀寫或錯誤的檔案
下面是一些跟select一起使用的函數及結構的作用
void FD_CLR(int fd, fd_set *set);//清空一個檔案描述符的集合int FD_ISSET(int fd, fd_set *set);//將一個檔案描述符添加到一個指定的檔案描述符集合中void FD_SET(int fd, fd_set *set);//將一個給定的檔案描述符從集合中刪除;void FD_ZERO(fd_set *set);//檢查集合中指定的檔案描述符是否可以讀寫
struct timeval結構是用來設定逾時時間的,該結構體可以精確到秒跟毫秒
struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */};
下面是select常用的一個例子:
#include <stdio.h>#include <stdlib.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>int main(int argc, cahr **argv) { struct timeval timeout; int ret = 0; fd_set rfds; FD_ZERO(&rfds);//清空描述符集合 FD_SET(0, &rfds);//將標準輸入(stdin)添加到集合中 FD_SET(sockfd, &rfds);//將我們的通訊端描述符添加到集合中 /*設定逾時時間*/ timeout.tv_sec = 1; timeout.tv_usec = 0; /*監聽通訊端是否為可讀*/ ret = select(sockfd+1, &rfds, NULL, NULL, &timeout); if(ret == -1) {//select 串連失敗 perror("select failure\n"); return 1; } else if(ret == 0) {//逾時(timeout) return 1; } if(FD_ISSET(pesockfd, &rfds)) {//如果可讀 //recv or recvfrom .................. } return 0; }
網路編程——select介紹