当前位置:网站首页>多路io复用
多路io复用
2022-06-09 21:18:00 【Gy648】
多路io复用 --select
这种方式可以同时监测多个文件描述符并且这个过程是阻塞的,一旦检测到有文件描述符就绪( 可以读数据或者可以写数据)程序的阻塞就会被解除,之后就可以基于这些(一个或多个)就绪的文件描述符进行通信了
select
委托内核帮助我们检测若干个文件描述符的状态
#include <sys/select.h>
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; //需要进行初始化,否则就是一个随机值 /* microseconds */
};
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval * timeout);
nfds:委托内核检测的这三个集合中最大的文件描述符 + 1,内核需要线性遍历这些集合中的文件描述符,这个值是循环结束的条件在 Window 中这个参数是无效的,指定为 - 1 即可
readfds:文件描述符的集合,内核只检测这个集合中文件描述符对应的读缓冲区这样才知道通过哪个文件描述符接收数据
writefds:文件描述符的集合,内核只检测这个集合中文件描述符对应的写缓冲区,如果不需要使用这个参数可以指定为 NULL
exceptfds:文件描述符的集合,内核检测集合中文件描述符是否有异常状态,如果不需要使用这个参数可以指定为 NULL
timeout:超时时长,用来强制解除 select () 函数的阻塞的
NULL:函数检测不到就绪的文件描述符会一直阻塞。
等待固定时长(秒):函数检测不到就绪的文件描述符,在指定时长之后强制解除阻塞,函数返回 0
不等待:函数不会阻塞,直接将该参数对应的结构体初始化为 0 即可。
函数返回值:
大于 0:成功,返回集合中已就绪的文件描述符的总个数
等于 - 1:函数调用失败
等于 0:超时,没有检测到就绪的文件描述符
void FD_CLR(int fd, fd_set *set);// 将文件描述符fd从set集合中删除 == 将fd对应的标志位设置为0
int FD_ISSET(int fd, fd_set *set);// 判断文件描述符fd是否在set集合中 == 读一下fd对应的标志位到底是0还是1
void FD_SET(int fd, fd_set *set);// 将文件描述符fd添加到set集合中 == 将fd对应的标志位设置为1
void FD_ZERO(fd_set *set); //将set集合中, 所有文件文件描述符对应的标志位设置为0, 集合中没有添加任何文件描述符
例子使用流程
前面准备工作不变,socket()->bind()->listen()
int lfd, cfd;
socklen_t client_len;
char buff[MAXLEN];
struct sockaddr_in serv_addr, client_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
lfd = socket(AF_INET, SOCK_STREAM, 0);
if (lfd == -1)
perr_exit("socket error ");
if (bind(lfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
perr_exit("bind error");
if (listen(lfd, 128) == -1)
perr_exit("listen error");
要设置一个遍历最大文件描述符的变量,进行进行更新,遍历的最大上限,初始大小设为socked所监听的文件描述符大小即可
int maxfd = lfd;
创建两个fd_set 型数组,用于存储和遍历,因为在遍历时可能会对里面参数作出改变所以创建一个用来当另一个副本,完成初始化和监听事件的添加
FD_ZERO(&redset);
FD_SET(lfd, &redset); //将监听的lfd设置到检测的读集合中
下面的处理已在后面编出完整注释
while (1)
{
tmp = redset; //创建副本
int cnt = select(maxfd + 1, &tmp, NULL, NULL, NULL);//表示需要监听的文件描述符的最大值 + 1,其实本质是一个线性表为了监听到最后一个文件描述符所以+1;
if (cnt < 0)
perr_exit("select error");
if (FD_ISSET(lfd, &tmp)) //判断是不是监听的lfd,是不是有新的客户端发起连接
{
cfd = accept(lfd, (struct sockaddr *)&client_addr, &client_len); //监听客户端,和发起请求的客户端建立连接
if (cfd == -1)
perr_exit("accept error");
FD_SET(cfd, &redset);//加入到原始的数组中
maxfd = cfd > maxfd ? cfd : maxfd;//判断 maxfd是不是当前最大上限
}
for (int j = lfd + 1; j <= maxfd; ++j) // j从lfd下一个开始即可
{
if (FD_ISSET(j, &tmp)) // 接受数据
{
int ret = read(j, buff, sizeof(buff));
if (ret == -1)
perr_exit("read error");
else if (ret == 0)
{
printf(" client close ----\n"); //该通信的客户端已经关闭
FD_CLR(j, &redset); //将其从集合中移出去
close(j);
}
else
{
for (int i = 0; i < ret; i++)
buff[i] = toupper(buff[i]);
ret = write(j, buff, ret);
if (ret == -1)
perr_exit("wirte error");
write(STDOUT_FILENO, buff, ret);
}
}
}
}
边栏推荐
- Beautify aria theme to rival charging theme mirages
- spider pi 智能视觉六足机器人 颜色追踪 人脸识别 0604
- 校园锐捷路由器使用指南
- SPIDER Pi Intelligent Vision hexapode Robot VNC Connect Robot 0603
- 【代码审计】buu_[GWCTF 2019]mypassword
- 202206007 模拟赛 总结
- Implementation principle and best practice of big data ecological security framework (Part I)
- Understand go modules' go Mod and go sum
- 【luogu P8330】众数(根号分治)
- 强烈推荐:数据标注平台doccano----简介、安装、使用、踩坑记录
猜你喜欢

Comprendre le go des modules go. MOD et go. SUM

Implementation principle and best practice of big data ecological security framework (Part I)

Unity get the content information of XML file

Wenxin Ernie 3.0 blessing! Small samples can also achieve 99% effect of full data!

winform编程 控件TreeView树视图的基本使用 20220527

Introduction to startup of spider PI intelligent vision hexapod robot 0602

Sqlserver2012 does not allow to modify the table structure 0607

深入理解 Go Modules 的 go.mod 与 go.sum

线程池

Load balancing configuration of EIGRP for daily technology sharing
随机推荐
swagger上的model和返回的数据字段不一致的问题
Thinking of finding the k-th largest element in O (n) by fast sorting
如何定位到服务器CPU飙高的原因
MFC connection database shows no data source name found and no default driver specified
怎么查期货平台是不是安全的?正规性怎么查
每日技术分享之EIGRP的负载均衡配置
Implementation principle and best practice of big data ecological security framework (Part I)
Spider PI intelligent vision hexapod robot color recognition function 0603
【代码审计】buu_[GWCTF 2019]mypassword
spider pi 智能视觉六足机器人 巡路功能 0603
Spider PI intelligent vision hexapod robot tag recognition apirltag tag 0604
Upper computer development (opening)
leetcode:547、朋友圈
Embedded software design (interim summary)
JS basic data type and reference data type
What is wave field TRX wallet development
spider pi 智能视觉六足机器人自动避障 0604
Mmdetection train your own coco data set and common problems
Pychart always displays the collecting data solution after entering the debug mode
强烈推荐:数据标注平台doccano----简介、安装、使用、踩坑记录