C++后台开发之网络IO模型

为了解决网络IO中的问题,学者们提出了4种网络IO模型:①阻塞IO模型;②非阻塞IO模型;③多路IO复用模型;④异步IO模型。

1.阻塞IO模型
在Linux中,默认情况下所有的socket都是阻塞的,阻塞和非阻塞的概念描述的是用户线程调用内核IO操作的方式:阻塞是指IO操作需要彻底完成后才返回到用户空间;而非阻塞是指IO操作被调用后立即返回给用户一个状态值,不需要等到IO操作彻底完成。典型

2.非阻塞IO模型
当用户进程发出read操作时,如果内核中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个错误。从用户进程角度讲,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果。当用户进程判断结果是一个错误时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦内核中的数据准备好了,并且又再次收到了用户进程的系统调用,那么它马上就将数据复制到了用户内存中,然后返回正确的返回值。
使用如下函数可以将fd换成非阻塞状态:

fcntl( fd, F_SETFL, O_NONBLOCK );

3.多路复用型IO模型
多路IO复用,有时也称为事件驱动IO。它的基本原理就是有个函数(如select)会不断地轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。

4.异步IO模型
用户进程发起read操作之后,立刻就可以开始去做其他的事;而另一方面,从内核的角度,当它收到一个异步的read请求操作之后,首先会立刻返回,所以不会对用户进程产生任何阻塞。然后,内核会等待数据准备完成

重点介绍多路复用IO模型中的三种函数,select,poll和epoll函数。

1.select函数

select函数原型如下:

int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval*timeout);

(1)参数maxfdp是一个整数值,是指集合中所有文件描述符的范围,其值为所有文件描述符的最大值加1。
(2)参数timeout是select的超时时间,这个参数至关重要,它可以使select处于3种状态:若传入参数timeout=NULL,那么select将处于阻塞态,直到监视到文件描述符集合中某个描述符变化为止;如果将参数timeout=0,则select将处于非阻塞状态,不管文件是否变化,有变化返回一个正值,无变化返回0;如果将参数timeout设置为大于0,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,超时返回0,有变化返回一个正值。
(3)readfds,writefds和errorfds表示分别指向fd_set 描述符集合的指针,分别监视描述符集合中描述符的读,写和异常变化。

fd_set 结构可以理解为一个fd的集合,其宏定义的控制函数如下所示:

fd_set set;

FD_ZERO(&set); /*将set清零*/

FD_SET(fd, &set); /*将fd加入set */

FD_CLR(fd, &set); /*将fd从set中清除*/

FD_ISSET;/*如果fd在set中则真,函数返回时,在set中的为变化描述符*/

例子程序:
使用select循环读取键盘输入:

#include "main.h"

int main(){

    int keyboard;

    int ret,i;

    char c;

    fd_set readfd;

    struct timeval timeout;
    //只读,非阻塞的方式打开
    keyboard = open("/dev/tty",O_RDONLY | O_NONBLOCK);

    assert(keyboard>0);

    while(1){

        timeout.tv_sec=1;

        timeout.tv_usec=0;

        FD_ZERO(&readfd);

        FD_SET(keyboard,&readfd);

        ret=select(keyboard+1,&readfd,NULL,NULL,&timeout);

        if(FD_ISSET(keyboard,&readfd)) {

        i=read(keyboard,&c,1);
        if('n'==c)
            continue;
        printf(
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值