半关闭、端口复用与IO多路复用

本文探讨了半关闭端口的复用问题,以及IO多路复用模型(如select、poll和epoll)的区别和各自的优缺点。重点对比了BIO(阻塞I/O)和NIO(非阻塞I/O)模型,并提供了针对不同场景的解决措施和工作模式优化建议。
摘要由CSDN通过智能技术生成

半关闭

使用close(fd);所对应的文件描述符写和读都关闭了。
在这里插入图片描述
在这里插入图片描述

端口复用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以解决绑定失败的问题。

IO多路复用(IO多路转接)

在这里插入图片描述
socket通信
io多路复用就是操作缓冲区
IO多路复用 是的程序能够同时监听多个文件描述符,能够提高程序的性能。
Linux下实现IO多路复用的系统调用主要有select、poll和epoll。

在这里插入图片描述

模型

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
每次循环遍历一遍,浪费资源。

BIO模型和NIO模型的区别

BIO(Blocking I/O)模型和NIO(Non-blocking I/O)模型是两种不同的I/O(Input/Output)模型,用于处理输入输出操作。

BIO模型:
BIO模型是一种阻塞式的I/O模型。在BIO模型下,当应用程序发起一个I/O请求时,它会被阻塞,直到操作系统完成相应的I/O操作才能继续执行后续代码。也就是说,在进行I/O操作期间,应用程序处于等待状态,无法处理其他任务。这种模型适合于连接数较少、每个连接负载较重的情况。

NIO模型:
NIO模型是一种非阻塞式的I/O模型。在NIO模型下,应用程序可以通过轮询操作系统来获取已经就绪的I/O事件,而不需要等待。它使用了事件驱动的方式,当一个I/O事件就绪时,应用程序会得到通知,然后可以立即处理该事件,而不需要等待其他I/O操作的完成。这种模型适合于连接数较多、每个连接负载较轻的情况。

总结一下,BIO模型是一种阻塞式的I/O模型,适用于连接数较少且每个连接负载较重的情况;而NIO模型是一种非阻塞式的I/O模型,适用于连接数较多且每个连接负载较轻的情况

解决措施

在这里插入图片描述
遍历标志位,检查
在这里插入图片描述

sellect

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

fd_set:为1024bit的标志位寄存器,是一个传入传出参数,将需要检测的文件描述符位置1传入,内核负责判断需要检测的文件描述符是否有IO操作,若有标志位依然为1,若没有则标志位置0,检测完成传出。
readfds:检测读缓冲区有数据了,可以读了,置1
writefds:检测写缓冲区还有空余空间可以写,置1
timeout:如果为NULL,表示永久阻塞,直到检测到了文件描述符变化;如果都=0, 不阻塞;如果时间>0,阻塞对应的时间。
返回值:
-1表示调用失败
>0:表示有几个文件描述符发生了变化

在这里插入图片描述

在这里插入图片描述

socket监听之后,进行文件描述符集合设置;
设置完成进行select,有文件描述符发生变化会有返回值,否则阻塞
判断哪个文件描述符发生了变换,进行相应的处理;
socket文件描述符发生变化,获取客户端连接文件描述符,并添加到集合
客户端连接文件描述符发生变化,对数据进行处理。

在这里插入图片描述
在这里插入图片描述
判断socket文件描述符,是否有新连接:
在这里插入图片描述
判断其他描述符,是否有数据来:
在这里插入图片描述
注意 : 上面的代码的问题是,设置rdset后传入传出后被修改了,下次传入不是想要的了,可以定义一个传入传出的集合tmp,一个设置的集合rdset,每次需要select时将设置集合赋值给tmp,进行操作。

缺点

在这里插入图片描述

poll

在这里插入图片描述
在这里插入图片描述
timeout:阻塞时间,单位为ms。
返回值:
-1:失败
>0(n):n个检测到集合中有n个文件描述符发生变化。
事件设置举例(通过|实现多个事件值):
在这里插入图片描述

应用

在这里插入图片描述
在这里插入图片描述

判断返回值,判断事件:
在这里插入图片描述
增加文件描述符:
从最开始向后遍历,找到最前面没有使用的文件描述符。
在这里插入图片描述
遍历搜索是哪个文件描述符发生事件,要从lfd开始,到最大文件描述符,索引下标则从0开始,到最大有文件描述符的下标。

缺点

在这里插入图片描述
改善了3.4条缺点,但其他依然存在。

epoll

创建,在内核就存在一个eventpoll实例,并返回内核缓冲区中的文件描述符
操作
检测
在这里插入图片描述
在这里插入图片描述
返回值:
-1:调用失败
>0:文件描述符,操作epoll的实例
在这里插入图片描述
三个事件分别是读、写、错误。
在这里插入图片描述
在这里插入图片描述

应用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意 :这个地方对epoll监听的事件如果有多种,就要对事件进行判断,防止出现错误判断应用;对其判断就是通过epevs[i].enents & EPOLL…进行判断(返回值与事件与)。

工作模式

LT模式和ET模式
在这里插入图片描述
上边缺省的工作方式就是默认工作方式。
读一次也算操作了,即使缓冲区里有数据也不重复通知,直到有新数据进来才会再进行新的通知。

两者区别:LT模式:
在这里插入图片描述
ET模式:
在这里插入图片描述
设置ET模式(在设置事件时或上EPOLLET):

在这里插入图片描述
在这里插入图片描述
再ET模式下数据读取可采用循环读取方式:
可以通过循环读取数据,直到读取结束,
read阻塞控制是由于文件描述符属性控制,所以可以通过设置文件描述符属性,改变为非阻塞:
需要头文件:
#include <fcntl.h>
#include <errno.h>

//设置cfd属性非阻塞
int flag = fcntl(cfd, F_GETFL);
flag |= O_NONBLOCK;
fcntl(cfd, F_SETFL, flag);

在这里插入图片描述
非阻塞情况,没有数据read会返回-1,错误号为EAGAIN,可通过判断处理
在这里插入图片描述

打印到终端的方式
write(STDOUT_FILENO, buf, len);
printf(“%s\n”, buf);

IO多路复用是同步还是异步?
epoll也是同步的
具体数据读取还是通过应用程序自己完成的
只有使用了特殊API调用才是异步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小猛笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值