#include <sys/select.h> #include <sys/time.h>
// 返回值:如有就緒描述符,則返回就緒描述符數目;若超時則返回0,出錯返回-1 int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout);
#include <sys/select.h> #include <sys/time.h> void FD_SET(int fd, fd_set *fdset); // 設置文件描述符集fdset中對應於文件描述符fd的位(設置爲1) void FD_CLR(int fd, fd_set *fdset); // 清除文件描述符集fdset中對應於文件描述符fd的位(設置爲0) void FD_ISSET(int fd, fd_set *fdset); // 檢測文件描述符集fdset中對應於文件描述符fd的位是否被設置 void FD_ZERO(fd_set *fdset); // 清除文件描述符集fdset中的全部位(既把全部位都設置爲0
注意:服務器
在使用FD_ISSET測試fd_set數據類型中的描述符後,描述符集內任何與未就緒描述符對應函數
的位返回時均被清0,所以,每次從新調用select函數時,都須要將描述符集內所關心的位置爲1測試
struct timeval{ long tv_sec; // 秒 long tv_usec; // 微秒 }
timeout參數的三種可能:
91 // 使用select的cli_io函數,使得在服務器進程終止後客戶能夠立刻獲取通知 92 void cli_io_select(int sockfd, char *mark, FILE *fp) 93 { 94 int maxfdp1, n; 95 fd_set rset; 96 char sendline[MAXLINE], recvline[MAXLINE]; 97 98 FD_ZERO(&rset); 99 100 for ( ; ; ) 101 { 102 FD_SET(fileno(fp), &rset); 103 FD_SET(sockfd, &rset); 104 105 // fileno() 函數,將文件流指針轉換爲文件描述符· 106 maxfdp1 = max(fileno(fp), sockfd) + 1; 107 108 if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0) 109 { 110 printf("Error select!\n"); 111 exit(1); 112 } 113 114 if (FD_ISSET(sockfd, &rset)) 115 { 116 if ( (n = read(sockfd, recvline, MAXLINE)) > 0 ) 117 { 118 recvline[n] = '\0'; 119 fputs(recvline, stdout); 120 } 121 } 122 123 if (FD_ISSET(fileno(fp), &rset)) 124 { 125 if (fgets(sendline, MAXLINE, fp) == NULL) 126 { 127 return; 128 } 129 130 if (write(sockfd, sendline, strlen(sendline)) < 0) 131 { 132 printf("Error write!\n"); 133 exit(1); 134 } 135 } 136 } 137 }