多路复用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 }

结果:

原文地址:https://www.cnblogs.com/chenyang920/p/5475549.html