多路复用IO一例
下面程序实现了功能是:
编写一个TCP服务器,只有一个进程,同时实现实时输出用户从键盘输入的数据,并且当有客户端的连接请求时,该服务器能迅速做出响应。
由上面的内容可知:该服务器的文件描述符有0(stdin),1(stdout),2(stderr)以及一个监听套接字描述符listenfd,和一个已连接套接字描述符confd。但只需要将描述符0和listenfd设置为多路复用IO即可。
代码如下:
1: #include <stdio.h>
2: #include <sys/socket.h>
3: #include <netinet/in.h>
4: #include <arpa/inet.h>
5: #include <strings.h>
6: #include <unistd.h>
7: #include <fcntl.h>
8: #include <sys/select.h>
9: #include <stdlib.h>
10:
11:
12: #define N 256
13: typedef struct sockaddr SA;
14:
15: int main(int argc, char *argv[])
16: {
17:
18: char buffer[N];
19: struct sockaddr_in myaddr;
20: int sockfd, confd;
21: fd_set rdfs;
22: int max_fd;
23: int i;
24:
25:
26:
27: if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
28: {
29: perror("fail to socket");
30: exit(-1);
31: }
32:
33: bzero(&myaddr, sizeof(myaddr));
34:
35: myaddr.sin_family = PF_INET;
36: myaddr.sin_port = htons(atoi(argv[2]));
37: myaddr.sin_addr.s_addr = inet_addr(argv[1]);
38:
39: if(bind(sockfd, (SA *)&myaddr, sizeof(myaddr)) < 0)
40: {
41: perror("fail to bind");
42: exit(-1);
43: }
44:
45: if(listen(sockfd, 5) <0)
46: {
47: perror("fail to listen");
48: exit(-1);
49: }
50: max_fd = sockfd;
51:
52:
53: while(1)
54: {
55: FD_ZERO(&rdfs);
56: FD_SET(STDIN_FILENO, &rdfs);
57: FD_SET(sockfd, &rdfs);
58:
59: if(select(max_fd + 1, &rdfs, NULL, NULL, NULL) < 0)
60: {
61: perror("fail to select ");
62: exit(-1);
63: }
64:
65: for(i = 0; i <= max_fd; i++)
66: {
67:
68: if(FD_ISSET(i, &rdfs))
69: {
70: if(i == STDIN_FILENO)
71: {
72: fgets(buffer, N, stdin);
73: printf("----------> %s", buffer);
74: }
75: else if(i == sockfd)
76: {
77: confd = accept(sockfd, NULL, NULL);
78: printf("client connection! %d\n", confd);
79: close(confd);
80: }
81: }
82:
83: }
84:
85:
86: }
87:
88:
89: return 0;
90: }
测试方法:
运行服务器,然后从键盘向该终端输入数据,再开一个窗口,通过使用telnet工具发起一次客户端的连接请求,使用方法:
telnet <服务器IP> <服务器的端口>
运行效果:
本文来自博客园,作者:摩斯电码,未经同意,禁止转载