背景介绍

如果服务器要同时处理网络上的套接字连接请求和本地的标准输入命令请求,那么如果我们使用accept来接受连接请求,则无法处理标准输入请求;类似地,如果在read中等待一个输入请求,则无法处理网络连接的请求。

所谓I/O多路复用机制,就是说通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但 select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而还有一种情况是异步IO,异步I /O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。

使用select实现IO多路复用

我们可以使用select函数来实现等待一组描述符准备好读。select函数处理类型为fd_set的集合,也叫做描述符集合。逻辑上,我们可以将描述符集合看成一个大小为n的位向量,每个位对应一个描述符。select函数是一个阻塞函数,即只有等到读集合中至少有一个描述符可以读时,就不会阻塞,开始处理请求了。

代码如下:

#include "csapp.h"//此程序是使用基于 IO多路复用的并发服务器void echo(int connfd)
{int n;char buf[MAXLINE];rio_t rio;rio_readinitb(&rio,connfd);//带缓冲的读取函数while((n=rio_readlineb(&rio,buf,MAXLINE))>0) {//向连接符写入内容printf("server received %d bytes \n",n);rio_writen(connfd,buf,n);}
}/*command是作为键盘输入时执行的驱动动作*/
void command(void) {char buf[MAXLINE];printf("you input just now!\n");//从标准输入中读取输入到buf中存储if(!fgets(buf,MAXLINE,stdin))exit(0);//输出buf中的数据printf("%s",buf);
}//主程序
int main(int argc,char **argv)
{   //监听符,连接符,端口号int listenfd,connfd,port;//套接字地址结构的大小socklen_t clientlen=sizeof(struct sockaddr_in);//新建套接字地址结构struct sockaddr_in clientaddr;//fd_set为描述符集合,此处定义了两个read_set,ready_set描述符集合,分别是读集合/准备好集合fd_set read_set,ready_set;//如果运行时参数小于2,则提示错误if(argc!=2) {fprintf(stderr,"usage :%s <port>\n",argv[0]);exit(0);}//将第二个参数转化为整型端口号,args to integerport=atoi(argv[1]);//打开端口号,返回监听描述符listenfd=open_listenfd(port);//清空读集合FD_ZERO(&read_set);//将标准输入加到读集合FD_SET(STDIN_FILENO,&read_set);//将监听描述符加到读集合FD_SET(listenfd,&read_set);//服务器监听处理主程序while(1) {//将读集合赋值给准备好集合ready_set=read_set;//select函数会要求内核挂起进程,等待一个或多个IO事件发生后,才将控制返回给应用程序,就像在下面的示例一样 select(listenfd+1,&ready_set,NULL,NULL,NULL);//有IO事件后,将判断是来自从键盘上键入命令还是从客户端发来的请求,分别给出不同的回应if(FD_ISSET(STDIN_FILENO,&ready_set))command();if(FD_ISSET(listenfd,&ready_set)) {connfd=accept(listenfd,(SA *)&clientaddr,&clientlen);printf("client connected!");//向连接符回送数据echo(connfd);//关闭连接符,释放资源close(connfd);}}
}

测试部分

zzw@zzw-ThinkPad-Edge-E430c:~$ telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
hello
zzw@zzw-ThinkPad-Edge-E430c:~/doc_main/CProgram/Concurrency$ ./select.o 9999
client connected!server received 7 bytes

最后强调一下,这里是同步的IO问题,并非异步。

转载于:https://my.oschina.net/zzw922cn/blog/493723

Unix C语言编写基于IO多路复用的小型并发服务器相关推荐

  1. Linux系统下基于IO多路复用的大规模可靠UDP服务器的实现(三)

    七.可靠性UDP的优化细节 4.5章节中,我们提到了KCP本身的优化提高,由于可靠性UDP是这个方案是否优秀的关键,而各种可靠UDP协议中都有TCP算法的影子,所以下面我们再仔细的谈一下这个部分.按照 ...

  2. 项目--基于http协议的小型web服务器

    在我们对网络的学习过程中,会接触到网络编程,我们在网络中可以深刻认识到服务器与客户端的交互,当我们输入网址时背后发生的一系列后端操作,为了加深我们对网络部分的学习,我们找到了一个开源项目TinyWeb ...

  3. 基于IO多路复用的TCP客户端

    为什么要采用IO多路复用 在开发的过程中,我们经常需要写多线程或多进程代码,但是无论多线程还是多进程,它们都是依附于操作系统存在的,一旦板子没有操作系统,这些操作都将无法完成.可是类似于多线程的操作却 ...

  4. nginx 多进程 + io多路复用 实现高并发

    一.nginx 高并发原理 简单介绍:nginx 采用的是多进程(单线程) + io多路复用(epoll)模型 实现高并发 二.nginx 多进程 启动nginx 解析初始化配置文件后会 创建(for ...

  5. 基于HTTP实现的小型web服务器

    主要流程为:服务器获得请求–>响应并处理请求–>返回结果. 完整的HTTP过渡到TCP实现客户端与服务器的交互过程 1.当客户端执行网络请求的时候,从url中解析出url的主机名,并将主机 ...

  6. c语言tcp硬时事通讯程序代码,使用C语言编写基于TCP协议的Socket通讯程序实例分享...

    tcp客户端示例 #include #include #include #include #include #include #include #include #include #include # ...

  7. 用c语言编写基于sht10传感器的仓库温湿度监测系统的程序,单片机远程仓库湿度监测系统仿真max487+sht11源程序+电路原理图...

    //**************************************************** //SHT11温度+湿度传感器,测量结果用LCD1602显示 //操作的关键部分是1.对照 ...

  8. 我们团队设计的一个基于微服务的高并发服务器架构

  9. 基于消息队列的UDP并发服务器v1

    UDP是无状态的,无法用TCP一样的并发服务器.我们可以用消息队列的方式模拟下. 首先,我们看消息队列节点 typedef struct msg_buf {int sockfd;struct sock ...

最新文章

  1. UGUI的优点新UI系统三效率高效果好
  2. Java获取文件路径
  3. 硅谷程序员佛系养生法:我不修bug, 谁修bug
  4. Jwt Token 的刷新机制设计
  5. LeetCode MySQL刷题——day1
  6. Android--------从一个包中的Avtivity创建另外另外一个包的Context
  7. postgresql 的 .pgpass密码文件的使用
  8. 2017.11.24
  9. 详解 Array.prototype.slice.call(arguments)
  10. Golang 变量申明方式
  11. 小学计算机片段教学案例,小学信息技术教学案例分析(张擘)
  12. ie和chrome浏览器下onproperty事件oninput onpropertychange的相应和相应属性的获取
  13. 酉矩阵(unitary matrix)
  14. 计算机吴军科学家个人故事,吴军:阅读与写作50讲+吴军个人成长书单
  15. jquery mobile_使用jQuery Mobile改善Web应用程序的安全性
  16. HDU - 1859 最小长方形
  17. GPS定位详解——涉及GPS版本变化、定位获取失败等常见问题。
  18. 微信小程序自动保留空格换行
  19. 【文件操作】c语言文件操作(上)
  20. 学情分析场景解读,助力教育机构提升课程质量和学员学习效果

热门文章

  1. Java中的测不准原理
  2. 鱼眼图像(fisheye image)通过几何变换形成透视图(a perspective view)[存疑]
  3. tensorflow 冻结梯度
  4. Python变量的理解与内存管理
  5. form窗口上放一个label,如何能找到这个label在哪个文件中使用
  6. 2020大学生网络安全知识总决赛模拟题错题集(9)
  7. 无线网络安全标准(转)
  8. 8月11日 网工学习 APR协议 传输层协议 TCP UDP 数据封装转发全过程
  9. 读书百客:《拟孙权答曹操书》赏析
  10. 为什么高防CDN将成为网站安全防护的必备?