码迷,mamicode.com
首页 > 其他好文 > 详细

I/O多路转接之select——基于TCP协议

时间:2016-05-28 23:33:36      阅读:557      评论:0      收藏:0      [点我收藏+]

标签:tcp   i/o   select   

  1. 关于select的基础知识

    a. select是系统提供的多路复用输入输出模型。它是用来监视多个文件句柄的状态变化。

    b. 程序会停在select等,直到被监视的文件句柄至少有一个发生了状态改变。

    c. 文件句柄是整数


  2. 函数

技术分享

a. 参数

nfds:需要监视的最大文件描述符值加1;

struct timeval结构用于描述一段时间长度,若超出这个时间,需要监视的描述符没有发生,则返回0。


技术分享


3.代码实现

 21     //
 22     int sock=socket(AF_INET,SOCK_STREAM,0);
 23     if(sock<0)
 24     {
 25         perror("socket");
 26         exit(1);
 27     }
 28     //
 28          //
 29     struct sockaddr_in local;
 30     local.sin_family=AF_INET;
 31     local.sin_port=htons(port);
 32     local.sin_addr.s_addr=inet_addr(ip);
 33     //
 34     if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
 35     {
 36         perror("bind");
 37         exit(2);
 38     }
 39     //
 40     if(listen(sock,_BACKLOG_)<0)
 41     {
 42         perror("listen");
 43         exit(3);
 44     }
 45     return sock;
 46 }
 47 int main(int argc,char*argv[])
 48 {
 49     if(argc!=3)
 50     {
 51         usage(argv[0]);
 52         exit(1);
 53     }
 54 
 55     char* ip=argv[1];
 56     int port=atoi(argv[2]);
 57 
 58     int listen_sock=startup(ip,port);
 59 
 60     int done=0;
 61     int new_sock=-1;
 62     struct sockaddr_in client;
 63     socklen_t len=sizeof(client);
 64 
 65     int max_fd;
 66     fd_set _reads;
 67     fd_set _writes;
 68 
 69     int i=0;
 70     int fds_num=sizeof(fds)/sizeof(fds[0]);
 71     for(;i<fds_num;++i)
 72     {
 73         fds[i]=-1;
 74     }
 75     fds[0]=listen_sock;
 76     max_fd=fds[0];
 77 
 78     while(!done)
 79     {
 80         FD_ZERO(&_reads);
 81         FD_ZERO(&_writes);
 82         FD_SET(listen_sock,&_reads);
 83         struct timeval _timeout={5,0};
 84         for(i=1;i<fds_num;++i)
 85         {
 86             if(fds[i]>0)
 87             {
 88                 FD_SET(fds[i],&_reads);
 89                 if(fds[i]>max_fd)
 90                 {
 91                     max_fd=fds[i];
 92                 }
 93             }
 94         }
 95         switch(select(max_fd+1,&_reads,&_writes,NULL,NULL))
 96         {
 97             case 0:
 98                 //timeout
 99                 printf("timeout\n");
100                 break;
101             case -1:
102                 perror("select");
103                 break;
104             default:
105                 {
106                     i=0;
107                     for(;i<fds_num;++i)
108                     {
109                         if(fds[i]==listen_sock&&FD_ISSET(fds[i],&_reads))
110                         {
111                             //listen socket is ready!
112                             new_sock=accept(listen_sock,(struct sockaddr*)&client,&len);
113                             if(new_sock<0)
114                             {
115                                 perror("accept");
116                                 continue;
117                             }
118                             printf("get a new connect...%d\n",new_sock);
119                             for(i=0;i<fds_num;++i)
120                             {
121                                 if(fds[i]==-1)
122                                 {
123                                     fds[i]=new_sock;
124                                     break;
125                                 }
126                             }
127                             if(i==fds_num)
128                             {
129                                 close(new_sock);
130                             }
131                         }
132                         //listen socket
133                         else if(fds[i]>0 && FD_ISSET(fds[i],&_reads))
134                         {
135                             char buf[1024];
136                             ssize_t _s=read(fds[i],buf,sizeof(buf)-1);
137                             if(_s>0)
138                             {
139                                 //read sucess
140                                 buf[_s]=‘\0‘;
141                                 printf("client:%s\n",buf);
142                             }
143                             else if(_s==0)
144                             {
145                                 //client shutdown
146                                 printf("client shutdown...\n");
147                                 close(fds[i]);
148                                 fds[i]=-1;
149                             }
150                             else
151                             {
152                                 perror("read");
153                             }
154                         }
155                         //normal socket
156                         else
157                         {}
158                     }
159                 }
160                 break;
161         }
162     }
163     return 0;
164 }


本文出自 “sunshine225” 博客,请务必保留此出处http://10707460.blog.51cto.com/10697460/1784034

I/O多路转接之select——基于TCP协议

标签:tcp   i/o   select   

原文地址:http://10707460.blog.51cto.com/10697460/1784034

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!