首页 > 其他 > 详细

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

时间:2019-08-04 11:38:25      阅读:74      评论:0      收藏:0      [点我收藏+]

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 ** argc)
 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! \n");
 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!\n");
 37     if(listen(serverfd,lisnum)==-1){
 38         perror("listen");
 39         return -3;
 40     }
 41     printf("listen OK!\n");
 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_fdset[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!\n");
 71             break;
 72         }
 73         else if(ret == 0){
 74             printf("timeout\n");
 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]:\n",i);
 82                ret = recv(client_sockfd[i],buffer,1024,0);
 83                if(ret <= 0){
 84                    printf("client[%d] close\n",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\n",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!\n");
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!\n");
109                 send(sock_client,buffer,1024,0);
110                 printf("new connection client[%d] %s:%d\n",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!\n");
115                     close(serverfd);
116                     return -1;
117                 }
118                 printf("recv: %s\n",buffer);
119                 if(sock_client > maxsock){
120                     maxsock = sock_client;
121                 }
122                 else{
123                     printf("max connection !!!quit!!\n");
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 }

 

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

原文:https://www.cnblogs.com/--lr/p/11296994.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!