select伺服器端的程式碼以及select的優缺點與多執行緒多程序伺服器的比較
阿新 • • 發佈:2019-02-11
22 struct sockaddr_in local;
23 local.sin_family=AF_INET;
24 local.sin_port=htons(port);
25 local.sin_addr.s_addr=inet_addr(ip);
26
27 if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
28 {
29 ┊ perror("bind");
30 ┊ exit(3);
31 }
32 if(listen(sock,10)<0)
33 {
34 ┊ perror("listen");
35 ┊ exit(4);
36 }
37 return sock;
38 }
39 static void usage(const char *proc)
40 {
41 printf("Usage:%s[local_ip][local_port]\n",proc);
42 }
43 int main(int argc,char* argv[])
44 {
45 if(argc!=3)
46 {
47 usage(argv[0]);
48 return 1;
49 }
50 int listen_sock=startup(argv[1],atoi(argv[2]));
51 int nums=sizeof(fds)/sizeof(fds[0]);
52 int i=0;
53 for(;i<nums;i++)
54 {
55 ┊ fds[i]=-1;
56 }
57 fds[0]=listen_sock;
58 while(1)
59 {
60 ┊ int max_fd=-1;
61 ┊ fd_set rfds;
62 ┊ FD_ZERO(&rfds);
63 ┊ for(i=0;i<nums;i++)
64 ┊ {
65 ┊ ┊ if(fds[i]>0)
66 ┊ ┊ {
67 ┊ ┊ ┊ FD_SET(fds[i],&rfds);
68 ┊ ┊ ┊ if(max_fd<fds[i])
69 ┊ ┊ ┊ {
70 ┊ ┊ ┊ ┊ max_fd=fds[i];
71 ┊ ┊ ┊ }
72 ┊ ┊ }
73 ┊ }
74 ┊ struct timeval timeout={1,0};
75 ┊ switch(select(max_fd+1,&rfds,NULL,NULL,&timeout))
76 ┊ {
77 ┊ ┊ case 0:
78 ┊ ┊ printf("timeout...\n");
79 ┊ ┊ break;
80 ┊ ┊ case -1:
81 ┊ ┊ perror("select");
82 ┊ ┊ default:
83 ┊ ┊ {
84 ┊ ┊ ┊ for(i=0;i<nums;i++)
85 ┊ ┊ ┊ {
86 ┊ ┊ ┊ ┊ if(fds[i]==-1)
87 ┊ ┊ ┊ ┊ {
88 ┊ ┊ ┊ ┊ ┊ continue;
89 ┊ ┊ ┊ ┊ }
90 ┊ ┊ ┊ ┊ if(i==0&&FD_ISSET(listen_sock,&rfds))
91 ┊ ┊ ┊ ┊ {
92 ┊ ┊ ┊ ┊ ┊ struct sockaddr_in client;
93 ┊ ┊ ┊ ┊ ┊ socklen_t len= sizeof(client);
94 ┊ ┊ ┊ ┊ ┊ int new_sock=accept(listen_sock,(struct sockaddr*)&client,&len);
95 ┊ ┊ ┊ ┊ ┊ if(new_sock<0)
96 ┊ ┊ ┊ ┊ ┊ {
97 ┊ ┊ ┊ ┊ ┊ ┊ perror("accept");
98 ┊ ┊ ┊ ┊ ┊ ┊ continue;
99 ┊ ┊ ┊ ┊ ┊ }
100 ┊ ┊ ┊ ┊ ┊ printf("get a new client:[%s:%d\n]", inet_ntoa(client.sin_addr),ntohs(client.sin_port));
101 ┊ ┊ ┊ ┊ ┊ int j=1;
102 ┊ ┊ ┊ ┊ ┊ for(;j<nums;j++)
103 ┊ ┊ ┊ ┊ ┊ {
104 ┊ ┊ ┊ ┊ ┊ ┊ if(fds[j]==-1)
105 ┊ ┊ ┊ ┊ ┊ ┊ {
106 ┊ ┊ ┊ ┊ ┊ ┊ ┊ break;
107 ┊ ┊ ┊ ┊ ┊ ┊ }
108 ┊ ┊ ┊ ┊ ┊ }
109 ┊ ┊ ┊ ┊ ┊ if(j==nums)
110 ┊ ┊ ┊ ┊ ┊ {
111 ┊ ┊ ┊ ┊ ┊ ┊ printf("client is full\n");
112 ┊ ┊ ┊ ┊ ┊ ┊ close(new_sock);
113 ┊ ┊ ┊ ┊ ┊ }
114 ┊ ┊ ┊ ┊ ┊ else
115 ┊ ┊ ┊ ┊ ┊ {
116 ┊ ┊ ┊ ┊ ┊ ┊ fds[i]=new_sock;
117 ┊ ┊ ┊ ┊ ┊ }
118 ┊ ┊ ┊ ┊ }
119 ┊ ┊ ┊ ┊ else if(i!=0&&FD_ISSET(fds[i],&rfds))
120 ┊ ┊ ┊ ┊ {
121 ┊ ┊ ┊ ┊ ┊ char buf[1024];
122 ┊ ┊ ┊ ┊ ┊ ssize_t s=read(fds[i],buf,sizeof(buf)-1);
123 ┊ ┊ ┊ ┊ ┊ if(s>0)
124 ┊ ┊ ┊ ┊ ┊ {
125 ┊ ┊ ┊ ┊ ┊ ┊ buf[s]=0;
126 ┊ ┊ ┊ ┊ ┊ ┊ printf("client#%s\n",buf);
127 ┊ ┊ ┊ ┊ ┊ }
128 ┊ ┊ ┊ ┊ ┊ else
129 ┊ ┊ ┊ ┊ ┊ {
130 ┊ ┊ ┊ ┊ ┊ ┊ perror("read");
131 ┊ ┊ ┊ ┊ ┊ ┊ close(fds[i]);
132 ┊ ┊ ┊ ┊ ┊ ┊ fds[i]=-1;
133 ┊ ┊ ┊ ┊ ┊ }
134 ┊ ┊ ┊ ┊ }
135 ┊ ┊ ┊ ┊ else
136 {
137
138 }
139 ┊ ┊ ┊ }
140 ┊ ┊ }
141 ┊ ┊ break;
142 ┊ }
143 }
144 return 0;
145 }
23 local.sin_family=AF_INET;
24 local.sin_port=htons(port);
25 local.sin_addr.s_addr=inet_addr(ip);
26
27 if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
28 {
29 ┊ perror("bind");
30 ┊ exit(3);
31 }
32 if(listen(sock,10)<0)
33 {
34 ┊ perror("listen");
35 ┊ exit(4);
36 }
37 return sock;
38 }
39 static void usage(const char *proc)
40 {
41 printf("Usage:%s[local_ip][local_port]\n",proc);
42 }
43 int main(int argc,char* argv[])
44 {
45 if(argc!=3)
46 {
47 usage(argv[0]);
48 return 1;
49 }
50 int listen_sock=startup(argv[1],atoi(argv[2]));
51 int nums=sizeof(fds)/sizeof(fds[0]);
52 int i=0;
53 for(;i<nums;i++)
54 {
55 ┊ fds[i]=-1;
56 }
57 fds[0]=listen_sock;
58 while(1)
59 {
60 ┊ int max_fd=-1;
61 ┊ fd_set rfds;
62 ┊ FD_ZERO(&rfds);
63 ┊ for(i=0;i<nums;i++)
64 ┊ {
65 ┊ ┊ if(fds[i]>0)
66 ┊ ┊ {
67 ┊ ┊ ┊ FD_SET(fds[i],&rfds);
68 ┊ ┊ ┊ if(max_fd<fds[i])
69 ┊ ┊ ┊ {
70 ┊ ┊ ┊ ┊ max_fd=fds[i];
71 ┊ ┊ ┊ }
72 ┊ ┊ }
73 ┊ }
74 ┊ struct timeval timeout={1,0};
75 ┊ switch(select(max_fd+1,&rfds,NULL,NULL,&timeout))
76 ┊ {
77 ┊ ┊ case 0:
78 ┊ ┊ printf("timeout...\n");
79 ┊ ┊ break;
80 ┊ ┊ case -1:
81 ┊ ┊ perror("select");
82 ┊ ┊ default:
83 ┊ ┊ {
84 ┊ ┊ ┊ for(i=0;i<nums;i++)
85 ┊ ┊ ┊ {
86 ┊ ┊ ┊ ┊ if(fds[i]==-1)
87 ┊ ┊ ┊ ┊ {
88 ┊ ┊ ┊ ┊ ┊ continue;
89 ┊ ┊ ┊ ┊ }
90 ┊ ┊ ┊ ┊ if(i==0&&FD_ISSET(listen_sock,&rfds))
91 ┊ ┊ ┊ ┊ {
92 ┊ ┊ ┊ ┊ ┊ struct sockaddr_in client;
93 ┊ ┊ ┊ ┊ ┊ socklen_t len= sizeof(client);
94 ┊ ┊ ┊ ┊ ┊ int new_sock=accept(listen_sock,(struct sockaddr*)&client,&len);
95 ┊ ┊ ┊ ┊ ┊ if(new_sock<0)
96 ┊ ┊ ┊ ┊ ┊ {
97 ┊ ┊ ┊ ┊ ┊ ┊ perror("accept");
98 ┊ ┊ ┊ ┊ ┊ ┊ continue;
99 ┊ ┊ ┊ ┊ ┊ }
100 ┊ ┊ ┊ ┊ ┊ printf("get a new client:[%s:%d\n]", inet_ntoa(client.sin_addr),ntohs(client.sin_port));
101 ┊ ┊ ┊ ┊ ┊ int j=1;
102 ┊ ┊ ┊ ┊ ┊ for(;j<nums;j++)
103 ┊ ┊ ┊ ┊ ┊ {
104 ┊ ┊ ┊ ┊ ┊ ┊ if(fds[j]==-1)
105 ┊ ┊ ┊ ┊ ┊ ┊ {
106 ┊ ┊ ┊ ┊ ┊ ┊ ┊ break;
107 ┊ ┊ ┊ ┊ ┊ ┊ }
108 ┊ ┊ ┊ ┊ ┊ }
109 ┊ ┊ ┊ ┊ ┊ if(j==nums)
110 ┊ ┊ ┊ ┊ ┊ {
111 ┊ ┊ ┊ ┊ ┊ ┊ printf("client is full\n");
112 ┊ ┊ ┊ ┊ ┊ ┊ close(new_sock);
113 ┊ ┊ ┊ ┊ ┊ }
114 ┊ ┊ ┊ ┊ ┊ else
115 ┊ ┊ ┊ ┊ ┊ {
116 ┊ ┊ ┊ ┊ ┊ ┊ fds[i]=new_sock;
117 ┊ ┊ ┊ ┊ ┊ }
118 ┊ ┊ ┊ ┊ }
119 ┊ ┊ ┊ ┊ else if(i!=0&&FD_ISSET(fds[i],&rfds))
120 ┊ ┊ ┊ ┊ {
121 ┊ ┊ ┊ ┊ ┊ char buf[1024];
122 ┊ ┊ ┊ ┊ ┊ ssize_t s=read(fds[i],buf,sizeof(buf)-1);
123 ┊ ┊ ┊ ┊ ┊ if(s>0)
124 ┊ ┊ ┊ ┊ ┊ {
125 ┊ ┊ ┊ ┊ ┊ ┊ buf[s]=0;
126 ┊ ┊ ┊ ┊ ┊ ┊ printf("client#%s\n",buf);
127 ┊ ┊ ┊ ┊ ┊ }
128 ┊ ┊ ┊ ┊ ┊ else
129 ┊ ┊ ┊ ┊ ┊ {
130 ┊ ┊ ┊ ┊ ┊ ┊ perror("read");
131 ┊ ┊ ┊ ┊ ┊ ┊ close(fds[i]);
132 ┊ ┊ ┊ ┊ ┊ ┊ fds[i]=-1;
133 ┊ ┊ ┊ ┊ ┊ }
134 ┊ ┊ ┊ ┊ }
135 ┊ ┊ ┊ ┊ else
136 {
137
138 }
139 ┊ ┊ ┊ }
140 ┊ ┊ }
141 ┊ ┊ break;
142 ┊ }
143 }
144 return 0;
145 }