Presentation is loading. Please wait.

Presentation is loading. Please wait.

网络应用程序设计 - unit 07 I/O 模型. 2 主要内容  I/O 模型  阻塞式 I/O 模型  非阻塞式 I/O 模型  输入输出多路复用 I/O 模型  信号驱动 I/O 模型.

Similar presentations


Presentation on theme: "网络应用程序设计 - unit 07 I/O 模型. 2 主要内容  I/O 模型  阻塞式 I/O 模型  非阻塞式 I/O 模型  输入输出多路复用 I/O 模型  信号驱动 I/O 模型."— Presentation transcript:

1 网络应用程序设计 - unit 07 I/O 模型

2 2 主要内容  I/O 模型  阻塞式 I/O 模型  非阻塞式 I/O 模型  输入输出多路复用 I/O 模型  信号驱动 I/O 模型

3 3 I/O 模型  Linux 系统 I/O 模型 阻塞式 I/O 模型-默认 I/O 模型 非阻塞式 I/O 模型 多路复用 I/O 模型 信号驱动 I/O 模型

4 4 阻塞式 I/O 模型  产生阻塞的原因 linux 进程调度算法-时间片调度算法  每个进程占用 CPU 一个时间片后被挂起  当前运行进程如果需要等待其他系统资源,且 不是非阻塞方式运行,将进入等待状态

5 5 阻塞式 I/O 模型  产生阻塞的函数-读操作 read 、 readv 、 recv 、 recvfrom 和 recvmsg 接收缓冲区无数据 拷贝数据 用户态核心态 read 数据到达 拷贝数据结束 read 返回 阻塞等待数据 状态 切换 状态 切换 TCP 协议以字节为单位, 只要接收缓冲区中出现数据, 进程被唤醒 UDP 协议以数据报为单位, 当完整的数据报到达时,进 程被唤醒 阻塞过程中,对方主机崩 溃,将永远阻塞

6 6 阻塞式 I/O 模型  产生阻塞的函数-写操作 write 、 writev 、 send 、 sendto 和 sendmsg 阻塞等待回 收数据缓冲区 发送缓冲区空间不足 拷贝数据 用户态核心态 write 得到数据确认, 空间足够 拷贝数据结束 write 返回 状态 切换 状态 切换 写操作发生阻塞的几率 低于读操作 TCP 协议写操作在对方 主机崩溃不会永远阻塞, 但需要等待较长时间 UDP 协议写操作永远不 会阻塞

7 7 阻塞式 I/O 模型  产生阻塞的函数-建立连接 connect 启动 3 次握手操作 用户态核心态 connect 连接建立完成 connect 返回 等待握手 操作完成 状态 切换 状态 切换 客户机 TCP 协议接收到服务器 TCP 协议返回的对 SYN 数据段 的确认时,函数 connect 成功 返回 TCP 协议的连接操作至少需要 一个往返时间 UDP 的 connect 操作不产生 连接,因此不阻塞

8 8 阻塞式 I/O 模型  产生阻塞的函数- TCP 协议接受连接 accept 没有已完成连接 创建连接 socket 用户态 核心态 accept 连接建立完成 连接 socket 建立成功 accept 返回 阻塞等待连接 状态 切换 状态 切换

9 9 阻塞式 I/O 模型  阻塞式 I/O 模型的特点 结构简单容易同步 进程可能永远阻塞或 阻塞时间过长 阻塞时进程效率低  示例: server.cpp client.cpp 数据到达 socket1 读阻塞 读数据 socket2 读阻塞 数据到达 读数据

10 10 阻塞式 I/O 模型  阻塞式 I/O 模型的超时控制 调用 alarm 函数设置超时  超时到达时产生 SIGALARM 信号中断 I/O 函数阻塞,对于 4 种产生阻塞的函数 均有效  多次调用 alarm 时,产生的 SIGALARM 信号无法区分是哪一次超时引发的,无 法实现超时控制  示例: alarmio.cpp

11 11 阻塞式 I/O 模型  阻塞式 I/O 模型的超时控制 设置 socket 选项  设置 SO_RCVTIMEO 和 SO_SNDTIMEO 选项 设置了这两个选项之后,所有的读写操作 可以保证在超时范围内返回 只需设置一次选项,对以后的读写操作均 有效 不适用于 accept 和 connect 示例: timeoutio.cpp

12 12 用户态 read read 返 回错误 read read 返回 接收缓冲 区无数据 数据到达 接收缓冲 区有数据 拷贝数 据完成 拷贝数据 核心态 状态 切换 状态 切换 状态 切换 状态 切换 非阻塞式 I/O 模型  非阻塞式 I/O 模型概述 可以设置 socket 为非阻 塞模式 在非阻塞模式 socket 上 进行 I/O 操作时,如果操 作不能完成,将以错误 返回 4 种 I/O 操作在非阻塞式 socket 下均不会阻塞

13 13 非阻塞式 I/O 模型  设置 socket 为非阻塞方式 函数 fcntl int flags; flag=fcntl(sockfd,F_GETFL,0); fcntl(sockfd,F_SETFL,flag|O_NONBLOCK); 函数 ioctl int on=1; ioctl(sockfd,FIONBIO,&on);

14 14 非阻塞式 I/O 模型  非阻塞式 I/O 模型对 4 种 I/O 操作返回的错误 读操作  接收缓冲区无数据时返回 EWOULDBLOCK 写操作  发送缓冲区无空间时返回 EWOULDBLOCK  空间不够时部分拷贝,返回实际拷贝字节数 建立连接  启动 3 次握手,立刻返回错误 EINPROGRESS  服务器客户端在同一主机上 connect 立即返回 成功 接受连接  没有新连接返回 EWOULDBLOCK

15 15 非阻塞式 I/O 模型  检查操作是否可以完成的方式 轮询式 for(;;){ if(read(sockfd,buf,nbytes)<0){ if(errno==EWOULDBLOCK)continue; else{ printf(“read error\n”); break; } else break; }

16 16 非阻塞式 I/O 模型  检查操作是否可以完成的方式 select 函数检查 I/O 是否就绪 // 设置监测的描述符集合 … // 阻塞等待描述符就绪 select( rdset, wrset, exset, …); // 对就绪描述符进行相应操作(读,写, … ) …

17 17 非阻塞式 I/O 模型  非阻塞式 I/O 模型特点 优点  不会产生阻塞  输入方式效率比较 高 缺点  长时间占用 CPU 示例:  server.cpp  client_n.cpp 数据到达 socket1 读失败 读数据 socket2 读失败 读数据 数据到达

18 18 输入输出多路复用 I/O 模型  多路复用模型 用户态 select select 返回 没有 socket 满足条件 阻塞等待任何一个 socket 就绪 一个或几个 socket 就绪 设置 socket 描述符集合完毕 设置就绪 socket 描述符 核心态 状态 切换 状态 切换

19 19 输入输出多路复用 I/O 模型  socket 描述符就绪条件 读就绪条件  接收缓冲区中的数据量 ≥ 接收下限。  读通道被关闭,收到 FIN 字段  侦听 socket 的完成连接队列不为空  非阻塞式 socket 的 connect 操作过程中 出现错误 默认接收下限为 1 ( TCP 为 1 字节, UDP 为 1 个数据报), 可以用 SO_RCVLOWAT 修改默认值

20 20 输入输出多路复用 I/O 模型  socket 描述符就绪条件 写就绪条件  发送缓冲区中可用空间 ≥ 发送下限。  写通道被关闭。  非阻塞式 socket 的 connect 操作成功 TCP 默认接收下限为 2048 字节,可以用 SO_SNDLOWAT 修改默认值 UDP 协议没有实际的发送缓冲区,其发送缓冲区空间总 是大于发送下限,所以 UDP socket 总是写就绪

21 21 输入输出多路复用 I/O 模型  socket 描述符就绪条件 异常就绪条件(用于带外数据)

22 22 输入输出多路复用 I/O 模型  多路复用 I/O 模型特点 只检查一个 socket 描 述符时和阻塞式 I/O 模 型类似,只是阻塞的 位置不同,但效率低 于阻塞式 I/O 模型 在多个 socket 描述符 上进行 I/O 操作时效率 高于阻塞式 I/O 示例 :client_m.cpp socket1 读第一个 socket 数据 socket2 读第二个 socket 数据 阻塞等待 socket 就绪

23 23 信号驱动 I/O 模型  信号驱动通信过程 用户态 设置 SIGIO 处理函数 read 返回 没有数据 到达 拷贝数据 核心态 状态 切换 状态 切换 信号处理函数 read 数据到达发送信号 SIGIO 执行其 他任务 SIGIO

24 24 信号驱动 I/O 模型  信号驱动 I/O 模型 的主要步骤 1. 设置 SIGIO 信号 处理函数 2. 设置 socket 描述 符所有者 3. 允许这个 socket 进行信号驱动 I/O void sigio_handler(int signo){ … } int main(){ int sockfd; int on=1; … signal(SIGIO,sigio_handler); fcntl(sockfd,F_SETOWN,getpid()); ioctl(sockfd,FIOASYNC,&on); … }

25 25 信号驱动 I/O 模型  信号驱动 I/O 模型特点 等待 I/O 操作可以进行的过程中不用阻塞, 可以执行其他操作 程序结构简单 更适用于 UDP 协议  TCP 协议在很多环节上会产生 SIGIO 信号,难 以区分产生信号的原因  UDP 只在收到数据包或错误时产生 SIGIO 信号 示例: sig_server.cpp,udpclient.cpp


Download ppt "网络应用程序设计 - unit 07 I/O 模型. 2 主要内容  I/O 模型  阻塞式 I/O 模型  非阻塞式 I/O 模型  输入输出多路复用 I/O 模型  信号驱动 I/O 模型."

Similar presentations


Ads by Google