标签:poll
不同于select使用三个位图来表示三个fdset的方式,poll使用一个pollfd的指针实现。
pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式。同时,pollfd并没有最大数量限制(但是数量过大后性能也是会下降)。和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。
从上面看,select和poll都需要在返回后,通过遍历文件描述符来获取已经就绪的socket。事实上,同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降。
代码描述:
server.c
1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<poll.h>
5 #include<time.h>
6 #include<unistd.h>
7 #include<sys/types.h>
8 #include<sys/socket.h>
9 #include<netinet/in.h>
10 #include<arpa/inet.h>
11
12 #define _BACKLOG_ 5
13 #define _SIZE_ 1024
14
15 void Usage(const char* proc)
16 {
17 printf("%s [ip][port]\n",proc);
18 }
19
20 int Start_sock(char* _ip,int _port)
21 {
22 int sock=socket(AF_INET,SOCK_STREAM,0);
23 if(sock<0)
24 {
25 perror("socket");
26 exit(1);
27 }
28 struct sockaddr_in local;
29 local.sin_family=AF_INET;
30 local.sin_port=htons(_port);
31 local.sin_addr.s_addr=inet_addr(_ip);
32 socklen_t len=sizeof(local);
33 if(bind(sock,(struct sockaddr*)&local,len)<0)
34 {
35 perror("bind");
36 exit(2);
37 }
38 if(listen(sock,_BACKLOG_)<0)
39 {
40 perror("listen");
41 exit(3);
42 }
43 return sock;
44 }
45 int main(int argc,char* argv[])
46 {
47 if(argc!=3)
48 {
49 Usage(argv[0]);
50 }
51 char* ip=argv[1];
52 int port=atoi(argv[2]);
53 int listen_sock=Start_sock(ip,port);
54
55 struct sockaddr_in cli;
56 socklen_t len=sizeof(cli);
57
58 struct pollfd _pfd[_SIZE_];
59 _pfd[0].fd=listen_sock;
60 _pfd[0].events=POLLIN;
61 _pfd[0].revents=0;
62
63 int i=0;
64 for(i=1;i<_SIZE_;++i)
65 {
66 _pfd[i].fd=-1;
67 _pfd[i].events=POLLIN;
68 _pfd[i].revents=0;
69 }
70 int done=0;
71 int timeout=5000;
72 int max=1;
73 while(!done)
74 {
75 switch(poll(_pfd,max,timeout))
76 {
77 case 0: //timeout
78 {
79 printf("timeout...\n");
80 break;
81 }
82 case -1: //errno
83 {
84 perror("poll");
85 break;
86 }
87 default:
88 {
89 for(i=0;i<_SIZE_;++i)
90 {
91 if(_pfd[i].fd==listen_sock&&_pfd[i].revents & POLLIN)
92 {
93 int new_sock=accept(_pfd[i].fd,(struct sockaddr*)&cl i,&len);
94 if(new_sock<0)
95 {
96 perror("accept");
97 continue;
98 }
99 int j=0;
100 for(j=0;j<_SIZE_;++j)
101 {
102 if(_pfd[j].fd<0)
103 {
104 _pfd[j].fd=new_sock;
105 _pfd[j].events=POLLIN;
106 _pfd[j].revents=0;
107 break;
108 }
109 }
110 if(j==_SIZE_)
111 {
112 printf("full");
113 close(new_sock);
114 }
115 max++;
116 printf("get a new connect:%d\n",new_sock);
117 }
118 else if(_pfd[i].fd>0&&_pfd[i].revents & POLLIN)
119 {
120 char buf[1024];
121 memset(buf,‘\0‘,sizeof(buf));
122 ssize_t _s=read(_pfd[i].fd,buf,sizeof(buf)-1);
123 if(_s<0)
124 {
125 perror("read");
126 close(_pfd[i].fd);
127 }
128 else if(_s==0)
129 {
130 printf(" client close...\n");
131 close(_pfd[i].fd);
132 }
133 else
134 {
135 buf[_s]=‘\0‘;
136 printf("client say:%s",buf);
137 write(_pfd[i].fd,buf,sizeof(buf)-1);
138 fflush(stdout);
139 }
140 }
141 else
142 {}
143 }
144 break;
145 }
146
147 }
148 }
149 return 0;
150 }client.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<unistd.h>
5 #include<sys/types.h>
6 #include<sys/socket.h>
7 #include<netinet/in.h>
8 #include<arpa/inet.h>
9
10 void Usage(const char* proc)
11 {
12 printf("%s [ip][port]\n",proc);
13 }
14
15 int main(int argc,char* argv[])
16 {
17 if(argc!=3)
18 {
19 Usage(argv[0]);
20 exit(1);
21 }
22 char* ip=argv[1];
23 int port=atoi(argv[2]);
24 int client_sock=socket(AF_INET,SOCK_STREAM,0);
25 if(client_sock<0)
26 {
27 perror("socket");
28 exit(2);
29 }
30 struct sockaddr_in remote;
31 remote.sin_family=AF_INET;
32 remote.sin_port=htons(port);
33 remote.sin_addr.s_addr=inet_addr(ip);
34
35 if(connect(client_sock,(struct sockaddr*)&remote,sizeof(remote))<0)
36 {
37 perror("connect");
38 exit(3);
39 }
40 char buf[1024];
41 while(1)
42 {
43 memset(buf,‘\0‘,sizeof(buf));
44 printf("please input:");
45 fflush(stdout);
46 fgets(buf,sizeof(buf)-1,stdin);
47 ssize_t _s=write(client_sock,buf,sizeof(buf)-1);
48 if(_s<0)
49 {
50 perror("write");
51 exit(4);
52 }
53 _s=read(client_sock,buf,sizeof(buf)-1);
54 if(_s<0)
55 {
56 perror("read");
57 exit(5);
58 }
59 else if(_s==0)
60 {
61 close(client_sock);
62 }
63 else
64 {
65 buf[_s]=‘\0‘;
66 printf("server->client:%s",buf);
67 fflush(stdout);
68 }
69 }
70 return 0;
71 }执行结果:
本文出自 “zwy” 博客,请务必保留此出处http://10548195.blog.51cto.com/10538195/1827530
标签:poll
原文地址:http://10548195.blog.51cto.com/10538195/1827530