Linux网络编程(四)

linux基本IO模型

Linux的IO模型

阻塞式IO模型(默认)

特点

  • 结构简单容易同步
  • 进程可能永远阻塞或阻塞时间过长
  • 阻塞时进程效率低

产生阻塞的函数-读操作:

read、readv、recv、recvfrom和recvmsg

TCP协议以字节为单位,只要接收缓冲区中出现数据,进程被唤醒

UDP协议以数据报为单位,当完整的数据报到达时,进程被唤醒

产生阻塞的函数-写操作

write、writev、send、sendto和sendmsg

  • 写操作发生阻塞的几率低于读操作
  • UDP协议写操作永远不会阻塞

产生阻塞的函数-建立连接

connect

  • 客户机TCP协议接收到服务器TCP协议返回的对SYN数据段的确认时,函数connect成功返回
  • TCP协议的连接操作至少需要一个往返时间
  • UDP的connect操作不产生连接,因此不阻塞

产生阻塞的函数-TCP协议接受连接

accept

阻塞式I/O模型的超时控制

调用alarm函数
  • 超时到达时产生SIGALARM信号中断I/O函数阻塞,对于4种产生阻塞的函数均有效
  • 多次调用alarm时,产生的SIGALARM信号无法区分是哪一次超时引发的,无法实现超时控制
设置socket选项

设置SO_RCVTIMEO和SO_SNDTIMEO选项,设置了这两个选项之后,所有的读写操作可以保证在超时范围内返回。只需设置一次选项,对以后的读写操作均有效
,不适用于acceptconnect

非阻塞IO模型

可以设置socket为非阻塞模式,在非阻塞模式socket上进行I/O操作时,如果操作不能完成,将以错误返回。4种I/O操作在非阻塞式socket下均不会阻塞。

一个示例如下图:

优缺点

优点:

  1. 不会产生阻塞
  2. 输入方式效率比较高

缺点:

  1. 长时间占用CPU

设置为非阻塞模式

#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);

其中request参数类别实在很多,就不总结了。简单说,如果设置非阻塞,就这样写:

ioctl(sockfd,FIONBIO,&on);

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );

同样,设置套接字为非阻塞IO的方法如下:

int flags;
flag=fcntl(sockfd,F_GETFL,0);//获取套接字sockfd的属性值
fcntl(sockfd,F_SETFL,flag|O_NONBLOCK);//将属性值或上非阻塞标志

对四种IO操作返回的错误

  • 读操作——接收缓冲区无数据时返回EWOULDBLOCK
  • 写操作——发送缓冲区无空间时返回EWOULDBLOCK;空间不够时部分拷贝,返回实际拷贝字节数
  • 建立连接——启动3次握手,立刻返回错误EINPROGRESS;服务器客户端在同一主机上connect立即返回成功
  • 接受连接——没有新连接返回EWOULDBLOCK

检查IO是否完成

  1. 轮询
  2. select函数

多路复用模型

简单说就是在等待的时候加入超时的时间,超时时间未到时和阻塞IO一致,到达超时时间后若仍然无数据就返回。

特点

  • 只检查一个socket描述符时和阻塞式I/O模型类似,只是阻塞的位置不同,但效率低于阻塞式I/O模型
  • 在多个socket描述符上进行I/O操作时效率高于阻塞式I/O

socket描述符读就绪

  • 接收缓冲区中的数据量≥接收最低限度(默认接收限度为1(TCP为1字节,UDP为1个数据报),可以用SO_RCVLOWAT修改默认值)。
  • 读通道被关闭,收到FIN字段
  • 侦听socket的完成连接队列不为空
  • 非阻塞式socket的connect操作过程中出现错误

socket描述符写就绪

  • 发送缓冲区中可用空间≥发送最低限度(TCP默认发送最低限度为2048字节,可以用SO_SNDLOWAT修改默认值;UDP协议没有实际的发送缓冲区,其发送缓冲区空间总是大于发送下限,所以UDP socket总是写就绪)。
  • 写通道被关闭。
  • 非阻塞式socket的connect操作成功

socket描述符异常就绪条件

用于带外数据。

信号驱动IO模型

在进程开始的时候注册一个信号处理的回调函数,当函数到达时,发送信号SIGIO,回调函数进行处理。

特点

  • 等待I/O操作可以进行的过程中不用阻塞,可以执行其他操作
  • 程序结构简单
  • 更适用于UDP协议
    • TCP协议在很多环节上会产生SIGIO信号,难以区分产生信号的原因
    • UDP只在收到数据包或错误时产生SIGIO信号

异步IO模型

与信号驱动IO模型类似,区别在于在数据复制完成时才发送信号,而信号驱动IO是数据到达就发送信号。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值