当前位置:网站首页>IO 复用
IO 复用
2022-08-03 05:23:00 【纸鸢805】
1. 端口复用设置
作用 : 解决address already is use 报错 的问题 ( 端口被占用, 可能没被释放 )
使用 : 放在socket 的 bind 前面;
int opt_val = 1;
//端口复用设置 socketfd1 网络连接标识符
setsockopt(socketfd1, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt_val, sizeof(opt_val));
2. socket IO复用
复用一般有三种技术
1. select
不记录发出 I/O 者的描述符, 因此只能无差别轮询所有流,找出能读出数据,或者写入数据的流,采用的是数组存储;
2. poll
poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态, 但是它没有最大连接数的限制,原因是它是基于链表来存储的。
3. epoll ( 下面介绍的函数就是epoll技术 )
应用场景
select的timeout参数精度为1nm,比poll和epoll的1ms精度更高,因此select适合实时性要求比较高的场景。select的可移植性非常的好。
poll没有最大描述符数量的限制,如果平台支持并且对实时性要求不高,应该使用poll而不是select
只需要运行在linux平台下,有大量的描述符需要同时轮询,并且这些连接最好时长连接。在监听少量的描述符的适合,体现不出epoll的优势。
2.1 关键函数
2.1.1 Epoll 的创建, 返回的是个数
int cpoll_size = epoll_create(int size);
2.1.2 Epoll 的操作 (增 删 改)
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
参数 :
epfd :
epoll 结构体对象
op :
EPOLL_CTL_ADD 注册新的fd到epfd中
EPOLL_CTL_MOD 修改已注册的fd的监听事件
EPOLL_CTL_DEL 从epfd中删除一个fd
fd :
要监听的描述符
event :
表示要监听的事件
2.1.3 epoll_wait 函数等待事件的就绪,成功时返回就绪的事件数目
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
例如:
epollwritefd = epoll_wait(epollfd, epolleventArr, 10, -1); //函数等待事件的就绪参数:
调用失败时返回 -1,等待超时返回 0。
epfd 是epoll句柄
events 表示从内核得到的就绪事件集合 maxevents 告诉内核events的大小
timeout 表示等待的超时事件
2.2 socket IO复用 的使用 :
1. 定义struct epoll_event 结构体的对象, 与struct epoll_event 结构体数组。
struct epoll_event epollevent;
struct epoll_event epolleventArr[10];
int epollfd = 0; //epollevent 的数量
int epollwritefd = 0; //epolleventArr[10] 的数量2. 设置 struct epoll_event 结构体对象监听的文件描述符 , 与监听事件( EPOLLIN )
epollevent.data.fd = socketfd1; //设置连接监听
epollevent.events = EPOLLIN; //设置监听的事件为有数据传输进来3. 创建 epoll
epollfd = epoll_create(10);
if (epollfd == -1)
{
perror(" epoll_create error ! ");
}4. epoll 添加
//添加 socketfd1 进 epollevent 中
epoll_ctl(epollfd, EPOLL_CTL_ADD, socketfd1, &epollevent);5 . 函数等待事件就绪
epollwritefd = epoll_wait(epollfd, epolleventArr, 10, -1); //函数等待事件的就绪
if ( epollwritefd <= 0 )
{
perror(" epoll_wait error ! ");
}6. 分为等待 客户端连接 与 客户端数据传递
循环 for (int i = 0; i < epollwritefd ; i++) 完成以下两种操作
// 客户端连接
if (epolleventArr[i].data.fd == socketfd1)
{
cout << epollfd << "服务器端正在等待客户端访问:" << endl;
//等待客户端访问, 阻塞函数
kehuduanfd = accept(socketfd1, NULL, NULL);
if (kehuduanfd == -1)
{
perror(" accept error ! ");
}
else
{
cout << "客户端 " << kehuduanfd << "访问服务器成功!" << endl;
epollevent.data.fd = kehuduanfd;
epollevent.events = EPOLLIN;
epoll_ctl(epollfd, EPOLL_CTL_ADD, kehuduanfd, &epollevent);
}
}// 客户端传输数据到服务器
if(epolleventArr[i].events & EPOLLIN)
{
cout << " 有数据传输不是客户端登录 " << endl;
bzero(&stu1, sizeof(stu1));
res = read(epolleventArr[i].data.fd, &stu1, sizeof(STU));
if ( res > 0 )
{
cout << " res = " << res << endl;
cout << "stu1.stuId = " << stu1.stuId << endl;
cout << "stu1.stuName = " << stu1.stuName << endl;
cout << "stu1.miaoshu = " << stu1.miaoshu << endl;
bzero(&stu1, sizeof(STU));
}
else if ( res <= 0 ) // 客户端下线 (读到的数据为 0 就是客户端有问题应该是下线了)
{
cout << "客户端 " << kehuduanfd << "关闭" << endl;
epollevent.data.fd = kehuduanfd;
epollevent.events = EPOLLIN;
epoll_ctl(epollfd, EPOLL_CTL_DEL, epolleventArr[i].data.fd, &epollevent);
close(epolleventArr[i].data.fd);
}
}
边栏推荐
- Execute the mysql script file in the docker mysql container and solve the garbled characters
- Leetcode刷题——一些用层次遍历解决的问题(111. 二叉树的最小深度、104. 二叉树的最大深度、226. 翻转二叉树、剑指 Offer 27. 二叉树的镜像)
- Browser multi-threaded off-screen rendering, compression and packaging scheme
- 【XSS,文件上传,文件包含】
- Haproxy服务监控
- 【CSRF,SSRF,XXE,PHP反序列化,Burpsuite】
- 【DC-5 Range Penetration】
- Go (一) 基础部分2 -- if条件判断,for循环语句
- Sentinel初次使用Demo测试
- Oracle 密码策略详解
猜你喜欢
随机推荐
【 command execution and middleware loopholes 】
中国食品产业园区行业前景规划建议及投融资模式分析报告2022~2028年
Kettle 从资源库中载入新的转换出错(Invalid byte 1 of 1-byte UTF-8 sequence)
MySql 怎么查出符合条件的最新的数据行?
中国生产力促进中心”十四五”规划与发展规模分析报告2022~2028年
MySQL 安装报错的解决方法
Sqli-labs-master shooting range 1-23 customs clearance detailed tutorial (basic)
【DC-2 Range Penetration】
动漫 吞噬星空
BeanFactory和FactoryBean的区别
当奈飞的NFT忘记了web2的业务安全
动漫:海贼王女
icebreaker的垃圾话学习指南
【DC-5靶场渗透】
陆运信息系统——班列项目总结(一)
Browser multi-threaded off-screen rendering, compression and packaging scheme
嵌入式实验四
Ansible installation and deployment detailed process, basic operation of configuration inventory
【DC-5 Range Penetration】
The ` monorepo ` ` hoist ` mechanism lead to the change of the loading configuration file path









