关于select的基础知识
a. select是系统提供的多路复用输入输出模型。它是用来监视多个文件句柄的状态变化。
b. 程序会停在select等,直到被监视的文件句柄至少有一个发生了状态改变。
c. 文件句柄是整数
函数
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
原文地址:http://10707460.blog.51cto.com/10697460/1784034