您的位置:首页 > 理论基础 > 计算机网络

Linux网络编程 IO多路复用

2016-03-10 16:49 761 查看

引言

首先,我们来说说多路复用出现是为解决什么问题,为什么要使用多路复用。回顾上网络编程的上一篇博客,我们不难发现,客户端在连接后就一直阻塞在read/fgets 上了,它一直再等待,我们从标准输入,输入内容进去,如果在这个时候服务器关闭,服务器会给客户端发送一个FIN分节消息给这个连接字,但是进程阻塞在标准输入上,根本看不到这个分节的消息,如果能够同时监控这两个消息,我们就会及时发现服务器关机并通知用户。

IO模型

        阻塞式IO





我们的工作就会一直阻塞,直到发现有可以读写的数据,才会返回

非阻塞式IO





非阻塞式IO 就是用一种轮询的方式,不停的尝试读取数据,读取不到就返回错误,接着再次尝试读取,这种操作非常耗费CPU。

IO复用模型





这里我们可以调用select 或者 poll 函数来监听多个文件描述符,当有消息课读或写的时候就通知我们工作的函数。

信号IO模型





这个模型首先注册一个信号函数,然后进程正常执行,当内核有数据的时候发送一个相应的信号,这时信号处理函数就会出来接收数据。

异步IO模型

 





 

这个异步模型在于它让内核完成所有的操作,完成后告诉我们它已经完成任务了。但是必须使用aio着类专门的函数。

5种结构的对比





 

select 函数

#include<select.h>

int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

void FD_CLR(int fd, fd_set *set);

int FD_ISSET(int fd, fd_set *set);

void FD_SET(int fd, fd_set *set);

void FD_ZERO(fd_set *set);

首先来解释下参数

@nfds  : 最大监视文件描述符

@readfds :读事件描述符集

@writefds:写事件描述符集

@exceptfds:  异常事件描述符集

@timeout :  返回时间测试

下面来看一个客户端--服务器的代码

简单回射服务器:





接着就是我们的工作函数str_cil





poll 函数

 

#include <poll.h>

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

struct pollfd {

int   fd;

short  events;         //感兴趣的事件

short  revents;         //实际发生的事件

}

这里我们在来看一个使用poll 的工作函数

 





这一部分就是我们服务器的正常启动到监听的过程,接着我们看看后边的使用





以上就是基本的IO复用,至于epoll 我们后边再说

查看原文:http://zmrlinux.com/2016/03/10/linux%e7%bd%91%e7%bb%9c%e7%bc%96%e7%a8%8b-io%e5%a4%9a%e8%b7%af%e5%a4%8d%e7%94%a8/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: