当前位置: 首页 > 服务器&&网络编程 > 正文

Linux网络编程 IO多路复用

引言

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

IO模型

        阻塞式IO

201205310957221562

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

非阻塞式IO

非

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

IO复用模型

F44IQaORa2

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

信号IO模型

170722_T6el_102078

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

异步IO模型

 

0747_JgRF_102078

 

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

5种结构的对比

21530930909591912

 

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 :  返回时间测试

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

简单回射服务器:

2016-03-10 16:26:31 的屏幕截图

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

2016-03-10 16:28:39 的屏幕截图

poll 函数

 

#include <poll.h>

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

struct pollfd {

int   fd;

short  events;         //感兴趣的事件

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

}

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

 

2016-03-10 16:44:25 的屏幕截图

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

2016-03-10 16:47:31 的屏幕截图

以上就是基本的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/ | Kernel & Me

该日志由 root 于2016年03月10日发表在 服务器&&网络编程 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: Linux网络编程 IO多路复用 | Kernel & Me