使用select函数提高服务器的处理能力

server.cpp

  1 #include <sys/types.h>
  2 #include <netinet/in.h>
  3 #include <unistd.h>
  4 #include <arpa/inet.h>
  5 //#include <windows.h>
  6 #include <sys/socket.h>
  7 //#include <winsock.h>
  8 
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 #include <string.h>
 12 #include <strings.h>
 13 //#include <sys/wait.h>
 14 #include <errno.h>
 15 
 16 #define DEFAULT_PORT 6666
 17 int main(int argc,char ** argv)
 18 {
 19     int serverfd,acceptfd;/*监听socket:serverfd,数据传输socket:acceptfd*/
 20     struct sockaddr_in my_addr;/*本机地址信息*/
 21     struct sockaddr_in their_addr;/*客户地址信息*/
 22     unsigned int sin_size,myport = 6666,lisnum = 10;
 23     if((serverfd = socket(AF_INET,SOCK_STREAM,0)) == -1){
 24         perror("socket");
 25         return -1;
 26     }
 27     printf("socket ok! 
");
 28     my_addr.sin_family = AF_INET;
 29     my_addr.sin_port = htons(DEFAULT_PORT);
 30     my_addr.sin_addr.s_addr = INADDR_ANY;
 31     bzero(&(my_addr.sin_zero),0);
 32     if(bind(serverfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1){
 33         perror("bind");
 34         return -2;
 35     }
 36     printf("bind OK!
");
 37     if(listen(serverfd,lisnum)==-1){
 38         perror("listen");
 39         return -3;
 40     }
 41     printf("listen OK!
");
 42     
 43     fd_set client_fdset;/*监控文件描述符集合*/
 44     int maxsock;        /*监控文件描述符中最大的文件号*/
 45     struct timeval tv;  /*超时返回时间*/
 46     int client_sockfd[5];/*存放活动的sockfd*/
 47     bzero((void*)client_sockfd,sizeof(client_sockfd));
 48     int conn_amount = 0; /*用来记录描述符数量*/
 49     maxsock = serverfd;
 50     char buffer[1024];
 51     int ret = 0;
 52     while(1){
 53         /*初始化文件描述符到集合*/
 54         FD_ZERO(&client_fdset);
 55         /*加入服务器描述符*/
 56         FD_SET(serverfd,&client_fdset);
 57         /*设置超时时间*/
 58         tv.tv_sec = 30;/*30秒*/
 59         tv.tv_usec = 0;
 60         /*把活动的句柄加到文件描述符中*/
 61         for(int i = 0; i < 5; i++){
 62             /*程序中Listen 中参数设置为5,故i要小于5*/
 63             if(client_sockfd[i]!=0){
 64                 FD_SET(client_sockfd[i],&client_fdset);
 65             }
 66         }
 67         /*select函数*/
 68         ret = select(maxsock+1,&client_fdset,NULL,NULL,&tv);
 69         if(ret < 0){
 70             perror("select error!
");
 71             break;
 72         }
 73         else if(ret == 0){
 74             printf("timeout
");
 75             continue;
 76         }
 77         /*轮询各个文件描述符*/
 78         for(int i = 0; i < conn_amount; i++){
 79            /* FD_ISSET检查是否client_sockfd是否可读写,>0可读写*/
 80            if(FD_ISSET(client_sockfd[i],&client_fdset)){  
 81                printf("start recv from client[%d]:
",i);
 82                ret = recv(client_sockfd[i],buffer,1024,0);
 83                if(ret <= 0){
 84                    printf("client[%d] close
",i);
 85                    close(client_sockfd[i]);
 86                    FD_CLR(client_sockfd[i],&client_fdset);
 87                    client_sockfd[i] = 0;
 88                 }
 89                 else{
 90                     printf("recv from client[%d]: %s
",i,buffer);
 91                 }
 92             }
 93         }
 94         /*检查是否有新的连接,如果有,接收连接,加入到client_sockfd中*/
 95         if(FD_ISSET(serverfd,&client_fdset)){
 96             /*接受连接*/
 97             struct sockaddr_in client_addr;
 98             size_t size = sizeof(struct sockaddr_in);
 99             int sock_client = accept(serverfd,(struct sockaddr*)(&client_addr),(unsigned int*)(&size));
100             if(sock_client <0){
101                 perror("accept error!
");
102                 continue;
103             }
104             /*把连接加入到文件描述符集合中*/
105             if(conn_amount < 5){
106                 client_sockfd[conn_amount++] = sock_client;
107                 bzero(buffer,1024);
108                 strcpy(buffer,"this is a server!welcome!
");
109                 send(sock_client,buffer,1024,0);
110                 printf("new connection client[%d] %s:%d
",conn_amount,inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
111                 bzero(buffer,sizeof(buffer));
112                 ret = recv(sock_client,buffer,1024,0);
113                 if(ret < 0){
114                     perror("recv error!
");
115                     close(serverfd);
116                     return -1;
117                 }
118                 printf("recv: %s
",buffer);
119                 if(sock_client > maxsock){
120                     maxsock = sock_client;
121                 }
122                 else{
123                     printf("max connection !!!quit!!
");
124                     break;
125                 }
126             }
127         }
128     }
129     for(int i = 0; i < 5; i++){
130         if(client_sockfd[i] != 0){
131             close(client_sockfd[i]);
132         }
133     }
134     close(serverfd);
135     return 0;
136 }

 Client.cpp

 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 <winsock.h>
 8 #include <netinet/in.h>
 9 #include <arpa/inet.h>
10 //#include <windows.h>
11 #include <errno.h>
12 #define DEFAULT_PORT 6666
13 
14 
15 int main(int argc,char *argv[])
16 {
17     int connfd = 0;
18     int cLen = 0;
19     struct sockaddr_in client;
20     if(argc < 2){
21         printf(" Uasge: clientent [server IP address]
");
22         return -1;
23     }
24     client.sin_family = AF_INET;
25     client.sin_port = htons(DEFAULT_PORT);
26     client.sin_addr.s_addr = inet_addr(argv[1]);
27     connfd = socket(AF_INET,SOCK_STREAM,0);
28     if(connfd < 0){
29         perror("socket");
30         return -1;
31     }
32     if(connect(connfd,(struct sockaddr*)&client,sizeof(client))<0){
33         perror("connect");
34         return -1;
35     }
36     char buffer[1024];
37     bzero(buffer,sizeof(buffer));
38     recv(connfd,buffer,1024,0);
39     printf("recv: %s
",buffer);
40     bzero(buffer,sizeof(buffer));
41     strcpy(buffer,"this is client!
");
42     send(connfd,buffer,1024,0);
43     while(1){
44         bzero(buffer,sizeof(buffer));
45         scanf("%s",buffer);
46         int p =strlen(buffer);
47         buffer[p] = '';
48         send(connfd,buffer,1024,0);
49         printf("i have send a buffer!
");
50     }
51     close(connfd);
52     return 0;
53 }

 makefile

 1 all:server client
 2 server:server.o
 3     g++ -g -o server server.o
 4 client:client.o
 5     g++ -g -o client client.o
 6 server.o:server.cpp
 7     g++ -g -c server.cpp
 8 client.o:client.cpp
 9     g++ -g -c client.cpp
10 clean:all
11     rm all
原文地址:https://www.cnblogs.com/--lr/p/11296994.html