这篇文章跟大家分析一下“I/O多路复用中select指的是什么”。内容详细易懂,对“I/O多路复用中select指的是什么”感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着小编一起深入学习“I/O多路复用中select指的是什么”的知识吧。
select是用于监视多个文件描述符状态的变化的。即用来监视文件描述符读/写/异常状态是否就绪。
函数原型:int select(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);
select的几大缺点:
(1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
(2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
(3)select支持的文件描述符数量太小了
1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<unistd.h>
5 #include<sys/select.h>
6
7 int main()
8 {
9 int std_in = 0;
10 // int std_out = 1;
11 fd_set reads;
12 // fd_set writes;
13 //int max_nums = std_out;
14 int max_nums = std_in;
15 FD_ZERO(&reads);
16 // FD_ZERO(&writes);
17 FD_SET(std_in,&reads);
18 // FD_SET(std_out,&writes);
19 struct timeval _timeout = {5,0};
20 int done = 0;
21 while(!done)
22 {
23 _timeout.tv_sec = 5;
24 _timeout.tv_usec = 0;
25 //switch(select(max_nums+1,&reads,&writes,NULL,&_timeout))
26 switch(select(max_nums+1,&reads,NULL,NULL,&_timeout))
27 {
28 case -1:
29 perror("select");
30 break;
31 case 0:
32 printf("timeout...\n");
33 break;
34 default://success
35 {
36 if(FD_ISSET(std_in,&reads))
37 {//read
38 char buf[1024];
39 memset(buf,'\0',sizeof(buf));
40 ssize_t size = read(std_in,buf,sizeof(buf)-1);
41 if(size<0)
42 {
43 perror("read");
44 exit(1);
45 }
46 if(strncmp(buf,"quit",4)==0)
47 {
48 done =1;
49 continue;
50 }
51 printf("echo: %s",buf);
52
53 }
54 // if(FD_ISSET(std_out,&writes))
55 // {//writes
56 // char buf[1024];
57 // while(1)
58 // {
59 // memset(buf,'\0',sizeof(buf));
60 // strcpy(buf,"hello world");
61 //write(1,buf,sizeof(buf)-1);
62 // printf("%s\n",buf);
63 // }
64 // }
65 break;
66 }
67 }
68 }
69 return 0;
70 }
[fbl@localhost select]$ ./select
hello
echo: hello
hi
echo: hi
nihao
echo: nihao
ahhau
echo: ahhau
quit
[fbl@localhost select]$
1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<unistd.h>
5 #include<sys/socket.h>
6 #include<sys/select.h>
7 #include<sys/types.h>
8 #include<netinet/in.h>
9 #include<arpa/inet.h>
10 #include<assert.h>
11
12 #define _BACKLOG_ 5
13 int fd[64];
14 void usage(char *_port)
15 {
16 printf("%s,[ip],[port]\n",_port);
17 }
18 int startup(char *ip,int port)
19 {
20 assert(ip);
21 int sock = socket(AF_INET,SOCK_STREAM,0);
22 if(sock<0)
23 {
24 perror("socket");
25 exit(1);
26 }
27 struct sockaddr_in local;
28 local.sin_family = AF_INET;
29 local.sin_port = htons(port);
30 local.sin_addr.s_addr = inet_addr(ip);
31 if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
32 {
33 perror("bind");
34 exit(2);
35 }
36 if(listen(sock,_BACKLOG_)<0)
37 {
38 perror("listen");
39 exit(3);
40 }
41 return sock;
42
43
44 }
45 int main(int argc,char *argv[])
46 {
47 if(argc!=3)
48 {
49 usage(argv[0]);
50 return 1;
51 }
52 int port = atoi(argv[2]);
53 char *ip = argv[1];
54 int listen_sock = startup(ip,port);
55 int new_sock = -1;
56 struct sockaddr_in client;
57 socklen_t len = sizeof(client);
58 fd_set reads;
59 fd_set writes;
60 int max_nums;
61 struct timeval _timeout = {5,0};
62 int done = 0;
63 int i =0;
64 int fd_nums = sizeof(fd)/sizeof(fd[0]);
65 for(;i<fd_nums;++i)
66 {
67 fd[i]=-1;
68 }
69 fd[0] = listen_sock;
70 while(!done)
71 {
72 _timeout.tv_sec = 5;
73 _timeout.tv_usec = 0;
74 FD_ZERO(&reads);
75 FD_ZERO(&writes);
76 for(i=0;i<fd_nums;++i)
77 {
78 if(fd[i]>0)
79 {
80 FD_SET(fd[i],&reads);
81 if(fd[i]>max_nums)
82 {
83 max_nums = fd[i];
84 }
85
86 }
87 }
88 switch(select(max_nums+1,&reads,&writes,NULL,&_timeout))
89 {
90 case -1:
91 perror("select");
92 break;
93 case 0:
94 printf("timeout...\n");
95 break;
96 default:
97 {
98
99 for(i=0;i<fd_nums;++i)
100 {
101 if(fd[i]==listen_sock && FD_ISSET(fd[i],&reads))
102 {
103 new_sock = accept(listen_sock,(struct sockaddr*) &client,&len);
104 if(new_sock<0)
105 {
106 perror("accept");
107 continue;
108 }
109 for(i=0;i<fd_nums;++i)
110 {
111 if(fd[i]==-1)
112 {
113 fd[i]=new_sock;
114 }
115 }
116
117 }
118 else if(fd[i]>0 && FD_ISSET(fd[i],&reads))
119 {
120 char buf[1024];
121 memset(buf,'\0',sizeof(buf));
122 ssize_t size = read(new_sock,buf,sizeof(buf)-1);
123 if(size<0)
124 {
125 perror("read");
126 exit(4);
127 }
128 else if(size==0)
129 {
130 printf("client close...\n");
131 close(fd[i]);
132 fd[i]=-1;
133 }
134 else
135 {
136 buf[size]='\0';
137 }
138 printf("client:%s\n",buf);
139 }
140 else
141 {}
142 }
143
144 break;
145 }
146
147 }
148 }
149 return 0;
150 }
1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<unistd.h>
5 #include<sys/socket.h>
6 #include<sys/select.h>
7 #include<sys/types.h>
8 #include<netinet/in.h>
9 #include<arpa/inet.h>
10 void usage(char *_port)
11 {
12 printf("%s,[ip],[port]\n",_port);
13 }
14 int main(int argc,char *argv[])
15 {
16 if(argc!=3)
17 {
18 usage(argv[0]);
19 return 1;
20 }
21 int port = atoi(argv[2]);
22 char *ip = argv[1];
23 int sock = socket(AF_INET,SOCK_STREAM,0);
24 if(sock<0)
25 {
26 perror("socket");
27 exit(1);
28 }
29 struct sockaddr_in remote;
30 remote.sin_family = AF_INET;
31 remote.sin_port = htons(port);
32 remote.sin_addr.s_addr = inet_addr(ip);
33 int ret = connect(sock,(struct sockaddr*)&remote,sizeof(remote));
34 if(ret<0)
35 {
36 perror("connect");
37 exit(1);
38 }
39 char buf[1024];
40 while(1)
41 {
42
43 memset(buf,'\0',sizeof(buf));
44 printf("please say:");
45 scanf("%s",buf);
46 ssize_t size = write(sock,buf,sizeof(buf)-1);
47 if(size<0)
48 {
49 perror("write");
50 exit(2);
51 }
52 else if(size ==0)
53 {}
54 else
55 {
56 printf("client : %s\n",buf);
57 }
58 }
59 return 0;
60 }
[fbl@localhost select_socket]$ ./server 192.168.1.106 8080
timeout...
client:hello
client:hi
client:huowo
client close...
client:
read: Bad file descriptor
[fbl@localhost select_socket]$
[fbl@localhost select_socket]$ ./client 192.168.1.106 8080
please say:hello
client : hello
please say:hi
client : hi
please say:huowo
client : huowo
please say:^C
[fbl@localhost select_socket]$
关于I/O多路复用中select指的是什么就分享到这里啦,希望上述内容能够让大家有所提升。如果想要学习更多知识,请大家多多留意小编的更新。谢谢大家关注一下亿速云网站!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。