zoukankan      html  css  js  c++  java
  • 使用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
  • 相关阅读:
    查询死锁和处理死锁(SqlServer)
    日期函数(SqlServer)
    [Shell] echo/输出 中引用命令
    Github 团队协作基本流程与命令操作 图解git工作流程
    HTML 引入 CSS、JS 的三种方式
    JavaScript 字符串匹配 | JS 的正则用法 | 从后边匹配
    Sublime + Chrome 本地调试 CSS 选择器
    常用 CSS 选择器
    使用 Sublime 或其他编辑器调试 Tampermonkey 油猴脚本
    使用 chrome 扩展 Vimium 实现快捷键关闭其他标签页
  • 原文地址:https://www.cnblogs.com/--lr/p/11296994.html
Copyright © 2011-2022 走看看