1. 程式人生 > >Select模式和超時

Select模式和超時

alt d+ lec cti ems int 分享圖片 stdout readn

技術分享圖片
 1      fd_set rset;
 2         FD_ZERO(&rset);
 3 
 4         int nready;
 5         int maxfd;
 6         int fd_stdin = fileno(stdin);
 7         if(fd_stdin > sock)
 8         {
 9                 maxfd = fd_stdin;
10         }
11         else
12         {
13                 maxfd = sock;
14 } 15 16 char sendbuf[1024] = { 0 }; 17 char recvbuf[1024] = { 0 }; 18 while(1) 19 { 20 FD_SET(fd_stdin,&rset); 21 FD_SET(sock,&rset); 22 nready = select(maxfd+1,&rset,NULL,NULL,NULL); 23 if
(nready == -1) 24 ERR_EXIT("select"); 25 if(nready == 0) 26 continue; 27 28 if(FD_ISSET(sock,&rset)) 29 { 30 31 int ret = readline(sock,recvbuf,sizeof(sendbuf)); 32 if
(ret == -1) 33 ERR_EXIT("readn"); 34 else if(ret == 0) 35 { 36 printf("server close"); 37 break; 38 } 39 40 fputs(recvbuf,stdout); 41 memset(sendbuf,0, sizeof(sendbuf)); 42 memset(recvbuf,0, sizeof(recvbuf)); 43 } 44 45 if(FD_ISSET(fd_stdin,&rset)) 46 { 47 if(fgets(sendbuf,sizeof(sendbuf),stdin) == NULL) 48 break; 49 writen(sock,sendbuf,strlen(sendbuf)); 50 } 51 } 52 close(sock);
View Code
  • 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);
  • select的超時
    •    技術分享圖片
        1 //讀超時
        2 int read_timeout(int fd,unsigned int wait_seconds)
        3 {
        4     int ret = 0;
        5     if(wait_seconds > 0)
        6     {
        7         fd_set read_fdset;
        8         struct timeval timeout;
        9         
       10         FD_ZERO(&read_fdset);
       11         FD_SET(fd,&read_fdset);
       12         
       13         timeout.tv_sec = wait_seconds;
       14         timeout.tv_usec = 0;
       15         do
       16         {
       17             ret = select(fd+1,&read_fdset,NULL,NULL,&timeout);
       18         }while(ret < 0 && errno == EINTR)
       19 
       20         if(ret == 0)
       21         {
       22             ret = -1;
       23             errno = ETIMEDOUT;
       24         }
       25         else if(ret == 1)
       26             ret = 0;
       27     }
       28     return ret;
       29 }
       30 
       31 
       32 //接收超時
       33 int accept_timeout(int fd,struct sockaddr_in *addr,unsigned int wait_seconds)
       34 {
       35     int ret;
       36     socklen_t addrlen = sizeof(struct sockaddr_in);
       37     
       38     if(wait_seconds > 0)
       39     {
       40         fd_set accept_fdset;
       41         struct timeval timeout;
       42         FD_ZERO(&accept_fdset);
       43         FD_SET(fd,&accept_fdset);
       44         timeout.tv_sec = wait_seconds;
       45         timeout.tv_usec = 0;
       46         do
       47         {
       48             ret = select(fd+1,&accept_fdset,NULL,NULL,&timeout);
       49         }while(ret < 0 && errno == EINTR)
       50         
       51         if(ret == -1)
       52             return -1;
       53         else if(ret == 0)
       54         {
       55             errno = ETIMEDOUT;
       56             return -1;
       57         }
       58     }
       59     if(addr != NULL)
       60         ret = accept(fd,(struct sockaddr*)addr,&addrlen);
       61     else
       62         ret = accept(fd,NULL,NULL);
       63     if(ret == -1)
       64         ERR_EXIT("accept");
       65     return ret;
       66 }
       67 
       68 void activate_nonblock(int fd)
       69 {
       70     int ret;
       71     int flags = fcntl(fd,F_GETFL);
       72     if(flags == -1)
       73         ERR_EXIT("fcntl");
       74     flags |= O_NONBLOCK;
       75     ret = fcntl(fd,F_SETFL,flags);
       76     if(ret == -1)
       77         ERR_EXIT("fcntl");
       78 }
       79 
       80 void deactivate_nonblock(int fd)
       81 {
       82     int ret;
       83     int flags = fcntl(fd,F_GETFL);
       84     if(flags == -1)
       85         ERR_EXIT("fcntl");
       86     flags &~ O_NONBLOCK;
       87     ret = fcntl(fd,F_SETFL,flags);
       88     if(ret == -1)
       89         ERR_EXIT("fcntl");
       90 }
       91 
       92 //連接超時
       93 int connect_timeout(int fd,struct sockaddr_in *addr, unsigned int wait_seconds)
       94 {
       95     int ret;
       96     socklen_t addrlen = sizeof(struct sockaddr_in);
       97 
       98     if(wait_seconds > 0)
       99         activat_nonblock(fd);
      100     
      101     ret = connect(fd,(struct sockaddr*)addr,addrlen);
      102     if(ret < 0 && errno == EINPROGRESS)
      103     {
      104         fd_set connect_fdset;
      105         struct timeval timeout;
      106         FD_ZERO(&connect_fdset);
      107         FD_SET(fd,&connect_fdset);
      108         timeout.tv_sec = wait_seconds;
      109         timeout.tv_usec = 0;
      110         do
      111         {
      112             ret = select(fd+1,NULL,&connect_fdset,NULL,&timeout);
      113         }while(ret < 0 && errno == EINTR)
      114         if(ret == 0)
      115         {
      116             ret = -1;
      117             errno = ETIMEDOUT;
      118         }
      119         else if(ret < 0)
      120             return -1;
      121         else if(ret == 1)
      122         {
      123             int err;
      124             socklen_t socklen = sizeof(err);
      125             int sockoptret = getsockopt(fd,SOL_SOCKET,SO_ERROR,&err,&socklen);
      126             if(sockoptret == -1)
      127             {
      128                 return -1;
      129             }
      130             if(err == 0)
      131                 ret = 0;
      132             else
      133             {
      134                 errno = err;
      135                 ret = -1;
      136             }
      137         }
      138     }
      139 
      140     if(wait_seconds > 0)
      141     {
      142         deactivate_nonblock(fd);
      143     }
      144     return ret;
      145 }
      View Code

Select模式和超時