Webserver(4.6)poll和epoll

目录

  • poll
    • client.c
    • poll.c
  • epoll
    • epoll.c
    • client.c
  • epoll的两种工作模式
    • 水平触发
    • 边沿触发

poll

poll是对select的一个改进
select的缺点在于每次都需要将fd集合从用户态拷贝到内核态,开销很大。每次调用select都需要在内核遍历传递进来的所有fd,这个开销也很大。select支持的文件描述符数量太小了,默认是1024。fds集合不能重用,每次都需要重置。
在这里插入图片描述
使用内核中的文件描述符在进行交互

client.c

#include<stdio.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>int main(){//1.创建套接字int fd=socket(AF_INET,SOCK_STREAM,0);if(fd==-1){perror("socket");exit(-1);}//2.连接服务器端struct sockaddr_in serveraddr;serveraddr.sin_family=AF_INET;inet_pton(AF_INET,"127.0.0.1",&serveraddr.sin_addr.s_addr);serveraddr.sin_port=htons(9999);int ret=connect(fd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));if(ret==-1){perror("connect");exit(-1);}//3.通信int num=0;while(1){char sendBuf[1024]={0};sprintf(sendBuf,"send data %d",num++);sleep(1);//给服务器发送数据write(fd,sendBuf,strlen(sendBuf)+1);int len=read(fd,sendBuf,sizeof(sendBuf));if(len==-1){perror("read");exit(-1);}else if(len>0){printf("recv server data:%s\n",sendBuf);}else if(len==0){//表示客户端断开连接printf("server closed...");}}//关闭连接close(fd);return 0;
}

poll.c

#include<stdio.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/time.h>
#include<sys/types.h>
#include<sys/select.h>
#include<poll.h>int main(){//创建socketint lfd=socket(PF_INET,SOCK_STREAM,0);struct sockaddr_in saddr;saddr.sin_port=htons(9999);saddr.sin_family=AF_INET;saddr.sin_addr.s_addr=INADDR_ANY;//绑定bind(lfd,(struct sockaddr *)&saddr,sizeof(saddr));//监听listen(lfd,8);//初始化检测的文件描述符数组struct pollfd fds[1024];for(int i=0;i<1024;i++){fds[i].fd=-1;fds[i].events=POLLIN;}fds[0].fd=lfd;int nfds=0;while(1){//调用poll系统函数,让内核帮检测哪些文件描述符有数据int ret=poll(fds,nfds+1,-1);if(ret==-1){perror("poll");exit(-1);}else if(ret==0){continue;}else if(ret>0){//说明检测到了有文件描述符的对应的缓冲区的数据发生了改变if(fds[0].revents&POLLIN){//表示有新的客户端连接进来了struct sockaddr_in cliaddr;int len=sizeof(cliaddr);int cfd=accept(lfd,(struct sockaddr *)&cliaddr,&len);//将新的文件描述符加入到集合中for(int i=1;i<1024;i++){if(fds[i].fd==-1){fds[i].fd=cfd;fds[i].events=POLLIN;break;}}//更新最大的文件描述符nfds=nfds>cfd? nfds:cfd;}for(int i=1;i<=nfds;i++){if(fds[i].revents&POLLIN){//说明这个文件描述符对应的客户端发来了数据char buf[1024]={0};int len=read(fds[i].fd,buf,sizeof(buf));if(len==-1){perror("read");exit(-1);}else if(len==0){printf("client closed..\n");close(fds[i].fd);fds[i].fd=-1;}else if(len>0){printf("read buf:%s\n",buf);write(fds[i].fd,buf,strlen(buf)+1);}}}}}close(lfd);return 0;
}

epoll

poll就是扩充了select的大小,用一个结构体集合去取代了这个集合
在这里插入图片描述

epoll.c

#include<stdio.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/time.h>
#include<sys/types.h>
#include<sys/epoll.h>int main(){//创建socketint lfd=socket(PF_INET,SOCK_STREAM,0);struct sockaddr_in saddr;saddr.sin_port=htons(9999);saddr.sin_family=AF_INET;saddr.sin_addr.s_addr=INADDR_ANY;//绑定bind(lfd,(struct sockaddr *)&saddr,sizeof(saddr));//监听listen(lfd,8);//调用epoll来创建一个epoll实例int epfd=epoll_create(100);//将监听的文件描述符相关的检测信息添加到epoll实例中struct epoll_event epev;epev.events=EPOLLIN;epev.data.fd=lfd;epoll_ctl(epfd,EPOLL_CTL_ADD,lfd,&epev);struct epoll_event epevs[1024];//用于接收监测后的数据,内核会返回进来while(1){int ret=epoll_wait(epfd,epevs,1024,-1);if(ret==-1){perror("epoll_wait");exit(-1);}printf("ret=%d\n",ret);for(int i=0;i<ret;i++){int curfd=epevs[i].data.fd;if(curfd==lfd){//监听的文件描述符有数据到达,即有客户端连接。客户端连接的信息都在lfd中//表示有新的客户端连接进来了struct sockaddr_in cliaddr;int len=sizeof(cliaddr);int cfd=accept(lfd,(struct sockaddr *)&cliaddr,&len);epev.events=EPOLLIN | EPOLLOUT;epev.data.fd=cfd;epoll_ctl(epfd,EPOLL_CTL_ADD,cfd,&epev);//accept得到的文件描述符添加到epfd这个实例中}else { //有数据到达,需要通信,说明不是监听的文件描述符。因为返回的是监听描述符说明是客户端连接,返回其他的文件描述符说明有数据到达。if(epevs[i].events&EPOLLOUT){continue;}//说明有数据到达,需要通信char buf[1024]={0};int len=read(curfd,buf,sizeof(buf));if(len==-1){perror("read");exit(-1);}else if(len==0){printf("client closed..\n");epoll_ctl(epfd,EPOLL_CTL_DEL,curfd,NULL);close(curfd);}else if(len>0){printf("read buf:%s\n",buf);write(curfd,buf,strlen(buf)+1);}}}}close(lfd);close(epfd);return 0;
}

client.c

#include<stdio.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>int main(){//1.创建套接字int fd=socket(AF_INET,SOCK_STREAM,0);if(fd==-1){perror("socket");exit(-1);}//2.连接服务器端struct sockaddr_in serveraddr;serveraddr.sin_family=AF_INET;inet_pton(AF_INET,"127.0.0.1",&serveraddr.sin_addr.s_addr);serveraddr.sin_port=htons(9999);int ret=connect(fd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));if(ret==-1){perror("connect");exit(-1);}//3.通信int num=0;while(1){char sendBuf[1024]={0};sprintf(sendBuf,"send data %d",num++);usleep(1000);//给服务器发送数据write(fd,sendBuf,strlen(sendBuf)+1);int len=read(fd,sendBuf,sizeof(sendBuf));if(len==-1){perror("read");exit(-1);}else if(len>0){printf("recv server data:%s\n",sendBuf);}else if(len==0){//表示客户端断开连接printf("server closed...");}}//关闭连接close(fd);return 0;
}

epoll的两种工作模式

水平触发

服务器一次只能读5个数据
在这里插入图片描述
客户端用键盘录入的方式发送信息
在这里插入图片描述
数据没有读完的话会一直通知,这是水平触发模式,直到读完为止

边沿触发

在这里插入图片描述
设置边沿触发
在这里插入图片描述
只收到了hello
但是再输入一次,会返回nihao,像挤牙膏一样一点一点得到缓冲区的数据
阻塞缓冲区
在这里插入图片描述
通过一个循环读取和非阻塞文件描述符,可以一次性读取

//循环读取出所有数据char buf[5];int len=0;while((len=read(curfd,buf,sizeof(buf))>0)){//将read设置为非阻塞,不然会堵在这出不来,就接收不了epoll_wait更新的情况//打印数据printf("recv data:%s\n",buf);write(curfd,buf,len);}if(len==0){printf("client closed...\n");}else if(len==-1){perror("read");exit(-1);}
//设置cfd为非阻塞int flag=fcntl(cfd,F_GETFL);flag | O_NONBLOCK;fcntl(cfd,F_SETFL,flag);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/7531.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

提高交换网络可靠性之认识STP根桥与端口角色

转载请注明出处 该实验旨在学习如何选举根桥与识别端口角色。 1.三台交换机按要求连线&#xff0c;改名&#xff0c;分别为S1&#xff0c;S2&#xff0c;S3&#xff0c;以S1为例&#xff1a; 2.在S1上配置优先级为28672 同理&#xff0c;在交换机S2和S3上配置其优先级为32768&…

qt QTextDocument详解

1、概述 QTextDocument是Qt框架中用于处理文本文档的类&#xff0c;它提供了丰富的功能和接口&#xff0c;用于创建、编辑和格式化文本内容。该类能够保存格式化的文本&#xff0c;是结构化富文本文档的容器&#xff0c;支持样式文本和各种文档元素&#xff0c;如列表、表格、…

【UE5】在材质中实现球形法线技术,常用于改善植物等表面的渲染效果

在材质中实现球形法线&#xff0c;这种技术常用于植被渲染等场景。通过应用球形法线可以显著提升植物再低几何体情况下的光照效果。 三二一上截图&#xff01; 当然也可以用于任何你希望模型圆润的地方&#xff0c;下图中做了一个Cube倒角

提高交换网络可靠性之链路聚合

转载请注明出处 该实验为链路聚合的配置实验。 1.改名&#xff0c;分别将交换机1和交换机2改名为S1&#xff0c;S2&#xff0c;然后查看S1&#xff0c;S2的STP信息。以交换机1为例&#x1f447;。 2.交换机S1&#xff0c;S2上创建聚合端口&#xff0c;将端口加入聚合端口。以S…

ZISUOJ 2024算法基础公选课练习一(3)

前言、 接&#xff08;2&#xff09;后完成I-J两道题 一、题目总览 二、具体题目 2.1 问题 I: 帆帆的图&#xff1a; 思路&#xff1a; 考察拓扑排序和图论&#xff08;拓扑排序也是排序&#xff0c;<滑稽>&#xff09;&#xff0c;都是模板&#xff0c;我就直接拿去…

窨井监测遥测终端RTU IP68防水强信号穿透力

在窨井的潮湿 黑暗和腐蚀性环境中 常规物联网设备往往难以生存 如何突破层层环境挑战 轻松应对极端条件 确保信号 24h不掉线&#xff0c;不延迟 不仅是对技术的突破 更是对恶劣环境的征服 ↓↓↓ 坚守 ——严苛环境下的工业设备 计讯物联工业级设备&#xff0c;专为恶劣环境设计…

python opencv3

三、图像预处理2 1、图像滤波 为图像滤波通过滤波器得到另一个图像。也就是加深图像之间的间隙&#xff0c;增强视觉效果&#xff1b;也可以模糊化间隙&#xff0c;造成图像的噪点被抹平。 2、卷积核 在深度学习中&#xff0c;卷积核越大&#xff0c;看到的信息越多&#xff0…

Mac上的免费压缩软件-FastZip使用体验实测

FastZip是Mac上的一款免费的压缩软件&#xff0c;分享一下我在日常使用中的体验 压缩格式支持7Z、Zip&#xff0c;解压支持7Z、ZIP、RAR、TAR、GZIP、BZIP2、XZ、LZIP、ACE、ISO、CAB、PAX、JAR、AR、CPIO等所有常见格式的解压 体验使用下来能满足我所有的压缩与解压的需求&a…

网络自动化04:python实现ACL匹配信息(主机与主机信息)

目录 背景分析代码代码解读代码总体结构1. load_pattern_from_excel 函数2. match_and_append_pattern 函数3. main 函数总结 最终的效果&#xff1a; 今天不分享netmiko&#xff0c;今天分享一个用python提升工作效率的小案例&#xff1a;acl梳理时的信息匹配。 背景 最近同事…

Linux之sed命令详解

文章目录 &#x1f34a;自我介绍&#x1f34a;sed概述&#x1f34a;sed语法讲解格式&#xff1a;options 命令选项{commmand}[flags] &#x1f34a;场景训练 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff…

用ChatGPT完成高质量文献综述全过程实操指南,用高级学术版专业应用gpts轻松搞定

文献综述在学术研究中占据核心地位,不仅为研究提供坚实的理论基础,也是创新观点和理论框架构建的重要支柱。然而,撰写高质量的文献综述往往是一项复杂且繁重的工作,需要研究者对领域内的文献进行广泛筛选、分类、对比和整合。该过程不仅考验研究者的分析能力,还要求对文献…

Java题目笔记(十四)Date +综合练习

一、时间计算时间比较 import java.util.Date; import java.util.Random;public class Main {public static void main(String[] args) {//需求1Date d1new Date(0L); //从时间原点开始经过了0毫秒long timed1.getTime();timetime1000L*60*60*24*365; //一年的时间d1.setTime(…

【C++练习】计算应发利润总数

题目&#xff1a;计算应发利润总数 问题描述&#xff1a; 某公司根据销售额 x&#xff08;单位&#xff1a;元&#xff09;计算应发利润总数 y&#xff08;单位&#xff1a;元&#xff09;&#xff0c;具体计算规则如下&#xff1a; 如果销售额 x 小于等于 100,000 元&#…

Permissions 0755 for ‘/etc/ssh/ssh_host_rsa_key‘ are too open.问题解决

1、问题背景 代码上库公司git后,将项目上出的程序烧录到设备中,wifi能够正常链接&#xff0c;但是通过wifi链接 ssh登录设备失败。把调试串口引出,查看linux启动log,发现如下打印信息&#xff1a; WARNING: UNPROTECTED PRIVATE KEY FILE! Permissions 075…

企业网络架构基础

1.网络宇宙 似宇宙洪荒&#xff0c;浩瀚无边&#xff0c;深不可测&#xff1b;网络案例似璀璨群星&#xff0c;千变万化&#xff0c;闪耀环宇。学习网络技术似夜观星象&#xff0c;每有所得&#xff0c;便拍案惊奇&#xff0c;夜不能寐 2.企业网络 企业网络已经广泛应用在各行…

Vue 3 的 全局状态管理

1.思路梳理 工厂仓拣货信息&#xff1a;Factory Picking Info (FPI)工厂仓调度信息&#xff1a;Factory Scheduling Info (FSI)DC 收货信息&#xff1a;DC Receiving Info (DCRI)上架信息&#xff1a;Shelving Info (SI)盘点信息&#xff1a;Inventory Count Info (ICI)移位信…

基于Spring Boot的在线装修管理系统的设计与实现,LW+源码+讲解

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#…

神经网络基础--什么是正向传播??什么是方向传播??

前言 本专栏更新神经网络的一些基础知识&#xff1b;这个是本人初学神经网络做的笔记&#xff0c;仅仅堆正向传播、方向传播就行了了一个讲解&#xff0c;更加系统的讲解&#xff0c;本人后面会更新《李沐动手学习深度学习》&#xff0c;会更有详细讲解;案例代码基于pytorch&a…

移动电源充气泵SIC8833应用方案设计

电动充气泵方案基于简单原理&#xff0c;使用时能自动检测轮胎压力。当胎压低于预设值时&#xff0c;电机自动启动&#xff0c;将压缩气体经进气管泵入轮胎。一旦充气泵达到设定的胎压上限&#xff0c;电机将自动关闭。该方案由压力传感器、ADC芯片、主控芯片等核心组件构成。其…

IP Source Guard

一、什么是IP Source Guard IP Source Guard&#xff08;IPSG&#xff09;是一种基于 IP/MAC 的端口流量过滤技术&#xff0c;用于防止局域网内的 IP 地址欺骗攻击。 隔绝非法DHCP服务器&#xff1a;通过配置非信任端口&#xff0c;IPSG可以有效阻止非法DHCP服务器向网络中的…