• 多路复用I/O模型select() 模型 代码实现


    多路复用I/O:  socket编程之select(),poll(),epoll()

    代码:

    client.c

     1 #include <stdio.h>
     2 #include <sys/types.h>
     3 #include <sys/stat.h>
     4 #include <stdlib.h>
     5 #include <string.h>
     6 #include <errno.h>
     7 #include <netinet/in.h>
     8 #include <sys/socket.h>
     9 #include <sys/select.h>
    10 #include <arpa/inet.h>
    11 #include <assert.h>
    12 #define maxn 1100
    13 #define IP  "127.0.0.1"
    14 #define PORT 45178
    15 #define MAXLINE 1024
    16 #define LISTENQ 5
    17 #define SIZE 10
    18 #define BACKLOG 2
    19 int main()
    20 {
    21     int sockfd;
    22     if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
    23     {
    24         printf("socket error!
    ");
    25         exit(1);
    26     }
    27     struct sockaddr_in server;
    28     bzero(&server,sizeof(server));
    29     server.sin_family = AF_INET;
    30     server.sin_port = htons(PORT);
    31     inet_pton(AF_INET,IP,&server.sin_addr);
    32     char buf[maxn];
    33     int connfd;
    34     connfd = connect(sockfd,(struct sockaddr*)&server,sizeof(server));
    35     if(connfd < 0)
    36     {
    37         printf("connect failure!
    ");
    38         return -1;
    39     }
    40     printf("client send to server
    ");
    41     printf("please input something
    ");
    42     scanf("%s",buf);
    43     write(sockfd,buf,maxn);
    44     char recvbuf[maxn];
    45     char sendbuf[maxn];
    46     fd_set readfd;
    47     int maxnum = 0;
    48     struct timeval T_time;
    49     int n;
    50     int sel_fd;
    51     while(1)
    52     {
    53         FD_ZERO(&readfd);
    54         FD_SET(sockfd,&readfd);
    55         maxnum = sockfd;
    56         T_time.tv_sec = 2;
    57         T_time.tv_usec = 0;
    58         sel_fd = select(maxnum + 1,&readfd,NULL,NULL,&T_time);
    59         if(sel_fd < 0)
    60         {
    61             continue;
    62         }
    63         else if(sel_fd == -1)
    64         {
    65             printf("select error!
    ");
    66             return;
    67         }
    68         if(FD_ISSET(sockfd,&readfd))
    69         {
    70             n = read(sockfd,recvbuf,maxn);
    71             if(n <= 0)
    72             {
    73                 printf("server is closed!
    ");
    74                 close(sockfd);
    75                 FD_CLR(sockfd,&readfd);
    76                 return;
    77             }
    78             printf("recv message is %s
    ", recvbuf);
    79             sleep(5);
    80             write(sockfd,buf,strlen(buf) + 1);
    81         }
    82     }
    83     close(sockfd);
    84     return 0;
    85 }

    server.c

      1 #include <stdio.h>
      2 #include <sys/types.h>
      3 #include <sys/stat.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 #include <errno.h>
      7 #include <netinet/in.h>
      8 #include <sys/socket.h>
      9 #include <sys/select.h>
     10 #include <arpa/inet.h>
     11 #include <assert.h>
     12 #define maxn 1100
     13 #define PORT 45178
     14 #define IP "127.0.0.1"
     15 #define MAXLINE 1024
     16 #define LISTENQ 5
     17 #define SIZE 10
     18 #define BACKLOG 2
     19 typedef struct server_context_st
     20 {
     21        int cli_num;        /*客户端个数*/
     22         int cli_fds[SIZE];   /*客户端的个数*/
     23       fd_set allfds;      /*句柄集合*/
     24         int maxfd;          /*句柄最大值*/
     25 } server_context_st;
     26 
     27 static int  init();
     28 static void deal_maxfd(int sockfd);
     29 static int accept_client(int sockfd);
     30 static void recv_client_msg(fd_set *readfd);
     31 static void submit_client_msg(int temp,char buf[]);
     32 static server_context_st *server_client = NULL;
     33 int Max(int a,int b);
     34 int Max(int a,int b)
     35 {
     36     return a>b?a:b;
     37 }
     38 static int server_init()
     39 {
     40     server_client = (server_context_st *)malloc(sizeof(server_context_st));
     41     if(server_client == NULL)
     42     {
     43         return -1;
     44     }
     45     memset(server_client,0,sizeof(server_context_st));
     46     int i=0;
     47     for(;i<SIZE;i++)
     48     {
     49         server_client->cli_fds[i] = -1;
     50     }
     51     return 0;
     52 }
     53 static int  init()
     54 {
     55 
     56     int sockfd;
     57     if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
     58     {
     59         printf("socket error!
    ");
     60         exit(1);
     61     }
     62     int listenfd;
     63     struct sockaddr_in server;
     64     bzero(&server,sizeof(server));
     65     server.sin_family = AF_INET;
     66     server.sin_port = htons(PORT);
     67     inet_pton(AF_INET,IP,&server.sin_addr);
     68     if(bind(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr)) == -1)
     69     {
     70         perror("bind error:");
     71         return -1;
     72     }
     73     listen(sockfd,BACKLOG);
     74     return sockfd;
     75 }
     76 static void deal_maxfd(int sockfd)
     77 {
     78     fd_set *readfd = &server_client->allfds;
     79     int sel_fd = 0;
     80     int clifd = -1;
     81     struct timeval T_time;
     82     while(1)
     83     {
     84         FD_ZERO(readfd);
     85         FD_SET(sockfd,readfd);
     86         server_client->maxfd = sockfd;
     87         T_time.tv_sec = 30;
     88         T_time.tv_usec = 0;
     89         
     90         int i;
     91         for(i=0;i<server_client->cli_num;i++)
     92         {
     93             clifd = server_client->cli_fds[i];
     94             FD_SET(clifd,readfd);
     95             server_client->maxfd =  Max(clifd,server_client->maxfd);
     96         }
     97         //retval = select(s_srv_ctx->maxfd + 1, readfds, NULL, NULL, &tv);
     98         sel_fd  = select(server_client->maxfd+1,readfd,NULL,NULL,&T_time);
     99         if(sel_fd == 0)
    100         {
    101             printf("time out!
    ");
    102             continue;
    103         }
    104         else if(sel_fd == -1)
    105         {
    106             printf("something error!
    ");
    107             return ;
    108         }
    109         if(FD_ISSET(sockfd,readfd))
    110         {
    111             /*监听客户端请求*/
    112             accept_client(sockfd);
    113         }
    114         else
    115         {
    116             /*接受处理客户端消息*/
    117             recv_client_msg(readfd);
    118         }
    119     }
    120 }
    121 static int accept_client(int sockfd)
    122 {
    123     struct sockaddr_in server_c;
    124     socklen_t len;
    125     len = sizeof (server_c);
    126     int afd = -1;
    127     Loop:
    128     printf("waiting ............................
    ");
    129     afd = accept(sockfd,(struct sockaddr*)&server_c,&len);
    130     if(afd == -1)
    131     {
    132         if(errno == EINTR)
    133         {
    134             goto Loop;
    135         }
    136         else
    137         {
    138              fprintf(stderr, "accept fail,error:%s
    ", strerror(errno));
    139             return -1;
    140         }
    141     }
    142     printf("accept successful!
    ");
    143     int i=0;
    144     for(i=0;i<SIZE;i++)
    145     {
    146         if(server_client->cli_fds[i] < 0)
    147         {
    148             server_client->cli_fds[i] = afd;
    149             server_client->cli_num ++;
    150             break;
    151         }
    152     }
    153     if(i == SIZE)
    154     {
    155         printf("too many client to accept!
    ");
    156         return -1;
    157     }
    158 }
    159 static void recv_client_msg(fd_set *readfd)
    160 {
    161     int i=0;
    162     int temp;
    163     char buf[maxn];
    164     for(i=0;i<server_client->cli_num;i++)
    165     {
    166         temp = server_client->cli_fds[i];
    167         if(temp < 0)
    168         {
    169             continue;
    170         }
    171         if(FD_ISSET(temp,readfd))
    172         {
    173             int n = read(temp,buf,maxn);
    174             if(n <= 0)
    175             {
    176                 FD_CLR(temp,&server_client->allfds);
    177                 close(temp);
    178                 server_client->cli_fds[i] = -1;
    179                 continue;
    180             }
    181             submit_client_msg(temp,buf);
    182         }
    183     }
    184 }
    185 static void submit_client_msg(int temp,char buf[])
    186 {
    187     assert(buf);
    188     printf("receive message is %s
    ",buf);
    189     write(temp,buf,strlen(buf)+1);
    190     return ;
    191 }
    192 int main()
    193 {
    194     if(server_init() == -1)
    195     {
    196         printf("init error
    ");
    197         return -1;
    198     }
    199     int sockfd;
    200     sockfd = init();
    201     deal_maxfd(sockfd);
    202     close(sockfd);
    203     return 0;
    204 }

    结果:

  • 相关阅读:
    关于2021-01-13爆发的incaseformat病毒相关信息收集1.2(持续更新和关注中...)
    (转)服务器UDIMM、LRDIMM、RDIMM三种内存的区别
    Shred命令 学习
    关于图片文件的元数据信息清理和时间戳修改
    关于Chrome 浏览器 “小尾巴”问题的解决办法
    CF471D MUH and Cube Walls -kmp
    UVA12467 Secret Word -kmp
    UVA12604 Caesar Cipher -kmp
    【JLOI2007】周期串
    Http协议
  • 原文地址:https://www.cnblogs.com/chenyang920/p/5475549.html
Copyright © 2020-2023  润新知