I/O多路复用(select)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Cell_KEY/article/details/52654850
#include<stdio.h>
  2 #include<sys/socket.h>
  3 #include<sys/types.h>
  4 #include<stdlib.h>
  5 #include<netinet/in.h>
  6 #include<arpa/inet.h>
  7 #include<assert.h>
  8 int rfds[128];
  9 void usage(char* proc)
 10 {
 11   assert(proc!=NULL);
 12   printf("Uage:%s: [ip] [port]\n",proc);
 13 }
 14 int start_up(const char* ip,int port)
 15 {
 16     assert(ip);
 17     assert(port>0);
 18     int sock=socket(AF_INET,SOCK_STREAM,0);
 19     if(sock<0){
 20       perror("socket");
 21       exit(2);
 22     }
 23     struct sockaddr_in local;
 24     local.sin_family=AF_INET;
 25     local.sin_port=htons(port);
 26     local.sin_addr.s_addr=inet_addr(ip);
 27 
 28     if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0){
 29        perror("bind");
 30        exit(3);
 31      }
 32     if(listen(sock,5)<0){
 33        perror("listen");
                                                                                                                                            1,
 34         exit(4);
 35     }
 36    return sock;
 37 }
 38 int main(int argc,char* argv[])
 39 {
 40    if( argc!=3 )
 41   {
 42     usage(argv[0]);
 43     return 1;
 44   }
 45   int listen_sock=start_up(argv[1],atoi(argv[2]));
 46   int i = 0;
 47   for(;i < 128; i++ ){
 48         rfds[i]=-1;
 49   }
 50   fd_set rset;
 51   int max_fd=0;
 52   while(1){
 53       struct timeval timeout={0,0};
 54       FD_ZERO(&rset);
 55       rfds[0]=listen_sock;
 56       max_fd=listen_sock;
 57       for(i=0; i <128; i++){
 58         if(rfds[i]>=0 ){
 59             FD_SET(rfds[i],&rset);
 60             if(max_fd<rfds[i]){
 61                 max_fd=rfds[i];
 62             }
 63          }
 64       }
 65   switch(select(max_fd+1, &rset, NULL, NULL, NULL) ){
  case -1://error
 67          perror("select");
 68          break;
 69     case 0://timeout
 70         printf("timeout...\n");
 71         break;
 72     default://success
 73         {
 74           int j=0;
 75           for(; j<128; j++){
 76              if(rfds[j]<0){
 77                  continue;
 78               }
 79              if(j==0 && FD_ISSET(rfds[j], &rset)){
 80               //new link
 81               struct sockaddr_in client;
 82               socklen_t len=sizeof(client);
 83               int new_fd=accept(listen_sock,\
 84                        (struct sockaddr*)&client, &len);
 85               if(new_fd<0 ){
 86                   perror("accept");
 87               }else{
 88                     printf("get a client: socket:%s:%d\n",\
 89                           inet_ntoa(client.sin_addr),\
 90                             ntohs(client.sin_port));
 91                      int k=0;
 92                      for(; k<128; k++){
 93                          if(rfds[k]==-1 ){
 94                               rfds[k]=new_fd;
 95                                break;
 96                           }
 97                       }
      if( k==128){
 99                          close(new_fd);
100                         }
101                  }
102             }else if( FD_ISSET(rfds[j], &rset)){
103                   //normal read
104                   char buf[1024];
105                   ssize_t s=read(rfds[j],buf,sizeof(buf)-1);
106                   if(s>0){
107                      buf[s]=0;
108                      printf("client# %s\n",buf);
109                    }else if(s==0){
110                         printf("client close...\n");
111                         close(rfds[j]);
112                         rfds[j]=-1;
113                    }else{
114                           perror("read");
115                          }
116              }else{
117                }
118            }
119        }
120         break;
121    }
122  }
123 }

猜你喜欢

转载自blog.csdn.net/Cell_KEY/article/details/52654850