zoukankan      html  css  js  c++  java
  • 多路复用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 }

    结果:

  • 相关阅读:
    Rainmeter 雨滴桌面 主题分享
    行人检測之HOG特征(Histograms of Oriented Gradients)
    const和readonly差别
    ADB命令解析
    Java实现 蓝桥杯VIP 算法训练 接水问题
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
  • 原文地址:https://www.cnblogs.com/chenyang920/p/5475549.html
Copyright © 2011-2022 走看看