0

0

I/O多路复用中select指的是什么

PHPz

PHPz

发布时间:2023-05-13 17:31:12

|

1703人浏览过

|

来源于亿速云

转载

select是用于监视多个文件描述符状态的变化的。即用来监视文件描述符读/写/异常状态是否就绪。

函数原型:int select(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);

select的几大缺点:

(1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大

CA.LA
CA.LA

第一款时尚产品在线设计平台,服装设计系统

下载

(2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大

(3)select支持的文件描述符数量太小了

  1 #include
  2 #include
  3 #include
  4 #include
  5 #include
  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
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 #include
  8 #include
  9 #include
 10 #include
 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(;i0)
 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;i0 && 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)
124124                             {
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
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 #include
  8 #include
  9 #include
 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]$

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

2

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

21

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

6

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

28

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

2

2026.01.15

ps图片相关教程汇总
ps图片相关教程汇总

本专题整合了ps图片设置相关教程合集,阅读专题下面的文章了解更多详细内容。

8

2026.01.15

ppt一键生成相关合集
ppt一键生成相关合集

本专题整合了ppt一键生成相关教程汇总,阅读专题下面的的文章了解更多详细内容。

3

2026.01.15

php图片上传教程汇总
php图片上传教程汇总

本专题整合了php图片上传相关教程,阅读专题下面的文章了解更多详细教程。

2

2026.01.15

phpstorm相关教程大全
phpstorm相关教程大全

本专题整合了phpstorm相关教程汇总,阅读专题下面的文章了解更多详细内容。

4

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号