多路复用I/O:一个执行体监视多个文件描述符对象的状态是否改变,一旦改变通知其他执行体来实现。

基本思想:

1、 先构造一张有关描述符的表,然后调用一个函数,当这些文件描述符中的一个或者多个已准备好进行I/O时函数才返回

2、 函数返回时告诉进程那个描述符已准备就绪,可以进行I/O操作。

Select(int n,fd_set *read_fds,fd_set *write_fds,fd_set *except_fds,struct timeval *timeout);

注意两点:

1、 select函数返回之前会将集合中状态未改变的fd清除

2、 返回值为状态改变的文件描述符对象的个数。

3、 Select阻塞时内部会产生一个线程盯着描述符对象的状态改变。

参数:n:maxfd,所有监控的文件描述符中值最大的加1;

Read_fds:是否可读的文件描述符集

Write_fds:是否可写的文件描述符集

Except_fds:出错的文件描述符集

Timeout:如果设置为NULL,则会一直阻塞,直到文件描述符的状态改变

Struct timeval

{

Long tv_sec;

Long tv_usec;

} ;

文件描述符的几个宏:

FD_ZERO(fd_set *fdset):清空文件描述符集

FD_SET(int fd,fd_set *fdset):将fd加入到fd_set集中

FD_ISSET(int fd,fd_set*fdset):判断fd是否在fdset中

FD_CLR(fd,fd_set *fdset);将fd从fdset集中清除

Select函数使用范例(功能:本例使用的是tcp,select监听标准输入是否准备好字符串可读然后发送和socketfd是否可读,然后接受,实现以简单的qq通信)

  1. 客户端:
  2. #include<stdio.h>
  3. #include<pthread.h>
  4. #include<netinet/in.h>
  5. #include<stdlib.h>
  6. #include<string.h>
  7. #include<strings.h>
  8. #include<sys/types.h>
  9. #include<sys/socket.h>
  10. int main()
  11. {
  12. int socketfd,ret;
  13. fd_set fd;
  14. FD_ZERO(&fd);
  15. FD_SET(,&fd);
  16.  
  17. socketfd = socket(PF_INET,SOCK_STREAM,);
  18. FD_SET(socketfd,&fd);
  19. ret = select(socketfd+,&fd,NULL,NULL,NULL);
  20. struct sockaddr_in saddr;
  21. memset(&saddr,,sizeof(saddr));
  22. saddr.sin_family = PF_INET;
  23. saddr.sin_port = htons();
  24. saddr.sin_addr.s_addr = inet_addr("192.168.1.46");
  25.  
  26. if(connect(socketfd,(struct sockaddr *)&saddr,sizeof(struct sockaddr))<)
  27.  
  28. perror("connect() error!\n");
  29. char buf[],buf1[];
  30. while()
  31. {
  32. bzero(buf,);
  33. bzero(buf1,);
  34.  
  35. FD_SET(,&fd);
  36. FD_SET(socketfd,&fd);
  37. ret = select(socketfd+,&fd,NULL,NULL,NULL);
  38. if(FD_ISSET(socketfd,&fd))
  39. {
  40. if(recv(socketfd,buf1,sizeof(buf1),)<)
  41. perror("recv() error!\n");
  42. printf("%s",buf1);
  43. continue;
  44. }
  45. if(FD_ISSET(,&fd))
  46. {
  47. // printf("please input:\n");
  48. fgets(buf,,stdin);
  49. if(send(socketfd,buf,strlen(buf),)<)
  50. perror("send() error!\n");
  51. continue;
  52. }
  53.  
  54. }
  55. }
  56. 服务器端:
  57. #include<stdio.h>
  58. #include<netinet/in.h>
  59. #include<stdlib.h>
  60. #include<string.h>
  61. #include <sys/types.h>
  62. #include <sys/socket.h>
  63. #include<pthread.h>
  64. #include<strings.h>
  65. int main()
  66. {
  67. int fds[];
  68. int maxfd = -;
  69. int socketfd = socket(PF_INET,SOCK_STREAM,);
  70. if(socketfd<maxfd)
  71. maxfd = socketfd;
  72. struct sockaddr_in saddr;
  73. memset(&saddr,,sizeof(saddr));
  74. saddr.sin_family = PF_INET;
  75. saddr.sin_port = htons();
  76. saddr.sin_addr.s_addr = inet_addr("192.168.193.2");
  77. int newsocketfd;
  78. int n = ;
  79. setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(int));
  80. if(bind(socketfd,(struct sockaddr*)&saddr,sizeof(struct sockaddr_in))<)
  81. perror("bind() error!\n");
  82.  
  83. if(listen(socketfd,)<)
  84. perror("listen() error!\n");
  85. struct sockaddr_in caddr;
  86. int s = sizeof(struct sockaddr);
  87. newsocketfd=accept(socketfd,(struct sockaddr*)&caddr,&s);
  88. fd_set fd;
  89. FD_ZERO(&fd);
  90. int ret;
  91. char buf[],buf1[];
  92. int i;
  93. int rsize;
  94. printf("hello\n");
  95. while()
  96. {
  97. bzero(buf,);
  98. bzero(buf1,);
  99. // printf("hello\n");
  100. FD_SET(,&fd);
  101. // printf("hello\n");
  102. FD_SET(newsocketfd,&fd);
  103. // printf("hello\n");
  104. select(newsocketfd+,&fd,NULL,NULL,NULL);
  105. if(FD_ISSET(newsocketfd,&fd))
  106. {
  107. // printf("hello\n");
  108. if(recv(newsocketfd,buf1,sizeof(buf1),)<)
  109. perror("recv() error!\n");
  110. printf("%s",buf1);
  111. // printf("hello\n");
  112. continue;
  113. }
  114.  
  115. if(FD_ISSET(,&fd))
  116. {
  117. fgets(buf,,stdin);
  118. if(send(newsocketfd,buf,strlen(buf),)<)
  119. perror("send() error!\n");
  120. continue;
  121. }
  122. }
  123. close(socketfd);
  124. close(newsocketfd);
  125.  
  126. }

多路复用select的更多相关文章

  1. 第五十五节,IO多路复用select模块加socket模块,伪多线并发

    IO多路复用select模块加socket模块,伪多线并发,并不是真正的多线程并发,实际通过循环等待还是一个一个处理的 IO多路复用,lo就是文件或数据的输入输出,IO多路复用就是可以多用户操作 IO ...

  2. Linux IO多路复用 select

    Linux IO多路复用 select 之前曾经写过简单的服务器,服务器是用多线程阻塞,客户端每一帧是用非阻塞实现的 后来发现select可以用来多路IO复用,就是说可以把服务器这么多线程放在一个线程 ...

  3. io多路复用-select()

    参照<Unix网络编程>相关章节内容,实现了一个简单的单线程IO多路复用服务器与客户端. 普通迭代服务器,由于执行recvfrom则会发生阻塞,直到客户端发送数据并正确接收后才能够返回,一 ...

  4. Linux 多路复用 select / poll

    多路复用都是在阻塞模式下有效! linux中的系统调用函数默认都是阻塞模式,例如应用层读不到驱动层的数据时,就会阻塞等待,直到有数据可读为止. 问题:在一个进程中,同时打开了两个或者两个以上的文件,读 ...

  5. I/O多路复用select/poll/epoll

    前言 早期操作系统通常将进程中可创建的线程数限制在一个较低的阈值,大约几百个.因此, 操作系统会提供一些高效的方法来实现多路IO,例如Unix的select和poll.现代操作系统中,线程数已经得到了 ...

  6. Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)

    Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...

  7. 【操作系统】I/O多路复用 select poll epoll

    @ 目录 I/O模式 I/O多路复用 select poll epoll 事件触发模式 I/O模式 阻塞I/O 非阻塞I/O I/O多路复用 信号驱动I/O 异步I/O I/O多路复用 I/O 多路复 ...

  8. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

  9. Python实战之IO多路复用select的详细简单练习

    IO多路复用 I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. select   它通过一个select()系统调用来 ...

随机推荐

  1. UE4 TSubclassOf VS Native Pointer

    最近看到了TSubclassOf ,所以想要弄清楚跟一般指针的区别~ NativePointer    VS     UClass*      VS     TSubclassOf AActor* p ...

  2. 【JavaScript_轮播图】

    今天给大家带来的是我自己做的一个轮播图效果,让我们一起来学习一下吧. 这是我的页面所有代码: <!DOCTYPE html> <html> <head> <m ...

  3. FileZilla出现Failed to convert command to 8 bit charset 

    FileZilla这款FTP客户端软件,自从华哥使用以来,采用其默认的设置,一直用得很顺畅,没有出现过什么问题.但是今天碰到了一个问题.如图. 错误信息为:Failed to convert comm ...

  4. 邓_Jquery测试题

    一.Jquery测试题 下面哪种不是jquery的选择器?(单选)A.基本选择器 B.后代选择器 C.类选择器 D.进一步选择器考点:jquery的选择器 (C) 当DOM加载完成后要执行的函数,下面 ...

  5. 【开发技术】Eclipse插件Call Hierarchy简介及设置

    Call Hierarchy 主要功能是 显示一个方法的调用层次(被哪些方法调,调了哪些方法) 在MyEclipse里Help - Software updates - Find and instal ...

  6. spring boot项目编译出来的jar包如何更改端口号

    执行的时候更改端口即可 . java -Dserver.port=9999 -jar boot.jar

  7. 修改ncnn的openmp异步处理方法 附C++样例代码

    ncnn刚发布不久,博主在ios下尝试编译. 遇上了openmp的编译问题. 寻找各种解决方案无果,亲自操刀. 采用std::thread 替换 openmp. ncnn项目地址: https://g ...

  8. 【WebApi系列】详解WebApi如何传递参数

    WebApi系列文章 [01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi参数的传递 [04]详解WebApi测试和PostMan [05]浅谈W ...

  9. Java - 路线图

    java语言基础 基本语法 面向对象思想 mysql数据库基础 jdbc操作 java高级技术 java集合框架 多线程 网络编程 sql深入,索引,sql优化 javaweb servlet jsp ...

  10. 黑窗口输入确定数字弹MessageBox(VirtualProtect())

    今天有人说到这个就想的弹一下,刚开始弄了一下,发现内存访问有问题想到可能与读写保护有关,所以用了VirtualProtect函数,得到了正确结果 网上这个小东西我自己没发现,就贴一下.. void m ...