epoll中listen socket的触发模式选择

十个问题理解Linux epoll工作原理 作者:dustinzhou,腾讯 IEG 运营开发工程师epoll 是 linux 特有的一个 I/O 事件通知机制。很久以来对 epoll 如何能够高效处理数以百万记的文件描述符很有兴趣... 阅读详情

epoll有两种触发模式,水平触发和边界触发。在监听listen socket的时候网上很多的代码里面选择边界触发,而且不是用while去accept,我们做如下的分析:建立listen socket之后,我们开始用epoll进行监听,如果某个时候很多请求到达,边界条件下触发了,但是我们调用accept处理一个连接,这个时候listen socket还有可读的,但是边界触发下,不会再触发了。也就是可能造成链接的丢失。

下面是一个简单的代码做一个测试:

服务器端的代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <sys/types.h>
#include <netinet/in.h>
#define MAXSOCKET 1024
#define BUFFSIZE  2048
void setnonblocking(int fd)
{
		int f;
		f=fcntl(fd,F_GETFL,0);
		if(f<0)
		{
				perror("fcntl error!f_getfl\n");
				exit(-1);
		}
		if(fcntl(fd,F_SETFL,f|O_NONBLOCK)<0)
		{
				perror("fcntl error!f_setfl\n");
				exit(-1);
		}
}
int main()
{
		int sockfd,connectfd,confds[MAXSOCKET];
		sockfd=socket(PF_INET,SOCK_STREAM,0);
		if(sockfd<0)
		{
				perror(strerror(errno));
				return -1;
		}
		unsigned value;
		setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&value,sizeof(value));
		memset(confds,0,MAXSOCKET);
		setnonblocking(sockfd);
		struct sockaddr_in server;
		socklen_t socklen=sizeof(struct sockaddr_in);
		memset(&server,0,socklen);
		server.sin_addr.s_addr=htonl(INADDR_ANY);
		server.sin_port=htons(8989);
		server.sin_family=AF_INET;
		if(bind(sockfd,(struct sockaddr *)&server,socklen)<0)
		{
				perror(strerror(errno));
				return -1;
		}
		int epollfd=epoll_create(MAXSOCKET);
		if(epollfd<0)
		{
				perror(strerror(errno));
				return -1;
		}
		struct epoll_event ev,events[MAXSOCKET];
		memset(&ev,0,sizeof(ev));
		ev.events=EPOLLIN|EPOLLET;
		ev.data.fd=sockfd;
		epoll_ctl(epollfd,EPOLL_CTL_ADD,sockfd,&ev);
		int count=0;
		int max=0;
		listen(sockfd,MAXSOCKET);
		char buf[BUFFSIZE];
		for(;;)
		{
				max=epoll_wait(epollfd,events,MAXSOCKET,0);
				if(max<0)
				{
						perror("epoll_wait error!\n");
						continue;
				}
				int i;
				for(i=0;i<max;++i)
				{
						if(events[i].data.fd==sockfd)
						{
								connectfd=accept(sockfd,NULL,NULL);
								if(connectfd<0)
								{
										perror("accept error!\n");
										continue;
								}
								printf("%d\n",count);
								count++;
								ev.events=EPOLLIN|EPOLLET;
								ev.data.fd=connectfd;
								epoll_ctl(epollfd,EPOLL_CTL_ADD,connectfd,&ev);
						}
						else
						{
								if(events[i].events&EPOLLIN)
								{
										int n=read(events[i].data.fd,buf,BUFFSIZE);
										if(n==0)
										{
												epoll_ctl(epollfd,EPOLL_CTL_DEL,events[i].data.fd,NULL);
												close(events[i].data.fd);
										}
								}
						}
				}
		}

}

服务器收到一个请求,计数器就加一并且输出。

客户端:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <pthread.h>
#define MAXTHREAD 512
void * startconnect(void *arg)
{
		int sockfd;
		char * ip=(char *)arg;
		sockfd=socket(AF_INET,SOCK_STREAM,0);
		if(sockfd<0)
		{
				perror(strerror(errno));
				return;
		}
		struct sockaddr_in client;
		memset(&client,0,sizeof(struct sockaddr));
		client.sin_family=AF_INET;
		client.sin_port=htons(8989);
		inet_pton(AF_INET,ip,&client.sin_addr.s_addr);
		//connect(sockfd,(struct sockaddr *)&client,sizeof(struct sockaddr));
		if(connect(sockfd,(struct sockaddr *)&client,sizeof(struct sockaddr))<0)
		{
				perror(strerror(errno));
				close(sockfd);
				return NULL;
		}
		close(sockfd);
		return NULL;
}
int main(int argc,char * argv[])
{
		if(argc<1)
		{
				perror("too few arguments!\n");
				return -1;
		}
		int sockfd;
		sockfd=socket(AF_INET,SOCK_STREAM,0);
		if(sockfd<0)
		{
				perror(strerror(errno));
				return -1;
		}
		pthread_t threads[MAXTHREAD];
		int i;
		for(i=0;i<MAXTHREAD;++i)
				threads[i]=pthread_create(threads+i,NULL,startconnect,argv[1]);
		return 0;
}

客户端用512个线程进行连接,客户端没有提示某个线程连接错误。执行的结果是服务器收到了480多个请求。

这是根据我个人的理解写的一个例子,有什么不对的地方请指正。

在epoll中添加一个刚创建的socket时的情况 今天读代码的时候,发现一个奇怪的操作: 一个线程在调用socket()函数后,并没有执行connect或listen操作 而是直接将这个socket加入了epoll中 来监听EPOLLIN时间 而在另外一个线程中 使用epoll_wait()却直接将这个socket作为一个就绪的描述符返回了 十分好奇这个socket是触发了什么事件,于是做了一个小实验,打印出了此socket触发时的 阅读详情

相关推荐

Android Socket 实现

Android Socket 实现 android是基于linux的操作系统,android中socket的实现也自然是基于linux的标准来。socket在android中的应用是非常广泛的,特别是在framework及以下层。那什么是socket?socket的类型有哪些?socket有哪些基本函数? 我们都知道本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类:

太妃糖的专栏 7721

linux epoll模型

转载自:http://www.cppblog.com/Khan/archive/2008/04/02/46013.html http://www.xmailserver.org/linux-patches/nio-improve.html     Linux I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数。Linux 2.6内核中有提高网络I/O性

liuhongxian的专栏 847

C++ Socket性能优化实战:从epoll到TCP_NODELAY的完整调优指南

网络编程是构建高性能服务器和分布式系统的核心技术,其核心在于高效管理大量并发连接和数据传输。理解其原理,关键在于掌握操作系统提供的I/O模型,如从传统的阻塞I/O到高效的I/O多路复用(如epoll),这决定了应用处理并发请求的能力上限。其技术价值在于能够显著提升吞吐量、降低延迟,并支撑起游戏服务器、金融交易系统等对实时性要求极高的应用场景。本文聚焦于C++ Socket编程的深度优化,通过剖析epoll边缘触发模式、TCP_NODELAY与TCP_CORK等关键选项,并结合缓冲区设置、分散聚集I/O等实战

aodanchui1057的博客 417

Linux Epoll ET模式EPOLLOUT和EPOLLIN触发时刻

Linux Epoll ET模式EPOLLOUT和EPOLLIN触发时刻 ET模式称为边缘触发模式,顾名思义,不到边缘情况,是死都不会触发的。 EPOLLOUT事件: EPOLLOUT事件只有在连接时触发一次,表示可写,其他时候想要触发,那你要先准备好下面条件: 1.某次write,写满了发送缓冲区,返回错误码为EAGAIN。 2.对端读取了一些数据,又重新...

weixin_33675507的博客 575

【驭风计划 机器学习】实验6 基于集成学习的 Amazon 用户评论质量预测

¶随着电商平台的兴起,以及疫情的持续影响,线上购物在我们的日常生活中扮演着越来越重要的角色。在进行线上商品挑选时,评论往往是我们十分关注的一个方面。然而目前电商网站的评论质量参差不齐,甚至有水军刷好评或者恶意差评的情况出现,严重影响了顾客的购物体验。因此,对于评论质量的预测成为电商平台越来越关注的话题,如果能自动对评论质量进行评估,就能根据预测结果避免展现低质量的评论。本案例中我们将基于集成学习的方法对 Amazon 现实场景中的评论质量进行预测。

Mege1的博客 471

Zemax非序列模式新手入门:从零搭建一个抛物面反射镜系统(含灯丝光源与探测器设置)

本文详细介绍了如何在Zemax非序列模式下从零搭建抛物面反射镜系统,包括灯丝光源配置、反射镜建模和探测器设置等关键步骤。通过实战指南,帮助光学设计新手快速掌握非序列模式的应用技巧,特别适合处理复杂光线传播场景如反射镜系统和杂散光分析。

weixin_28717431的博客 436

epoll使用详解(精髓)

epoll - I/O event notification facility在linux的网络编程中,很长的时间都在使用select来做事件触发。在linux新的内核中,有了一种替换它的机制,就是epoll。相比于select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率。因为在内核中的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗时越多。并且,在linu

ljx0305的专栏 28万+

基于RTL8367S与XS2184的工业级POE交换机硬件设计全解析

本文深入解析基于RTL8367S与XS2184芯片的工业级POE交换机硬件设计,涵盖核心价值、芯片选型、原理图设计、PCB布局及可靠性验证等关键环节。重点探讨双芯片协同工作优势,如RTL8367S的自适应调度算法和XS2184的智能功率分配功能,为工业环境下的稳定供电与数据传输提供专业解决方案。

weixin_42614269的博客 458

网络socket编程--epoll 模型原理详解以及实例

1.简介 Linux I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数。Linux 2.6内核中有提高网络I/O性能的新方法,即epoll 。 epoll是什么?按照man手册的说法是为处理大批量句柄而作了改进的poll。要使用epoll只需要以下的三个系统函数调用: epoll_create(2),epoll_ctl(2),epoll_wait(2)。 ...

$好记性还是要多记录$ 4222

从实验室到晶圆厂:一文看懂二维半导体(如MoS2)的CVD生长与晶体管制造挑战

本文深入探讨了二维半导体(如MoS2)从实验室研究到晶圆厂量产的CVD生长与晶体管制造关键技术挑战。重点分析了晶圆级二维半导体的CVD生长工艺优化、晶体管制造的四大界面工程难题,以及掺杂与集成的产业化解决方案,为二维半导体在集成电路领域的应用提供技术参考。

weixin_42651748的博客 472

辉芒微教程第五篇《定时器0实现LED灯闪烁》

定时器定时器,一听就跟个闹钟似的,对于嵌入式定时器大部分的应用中,也的确可以这么理解,但是这只能肤浅地这么理解,实际其功能不仅仅是用来计数定时,但是对于我们这种8位单片机,这么理解就够了。

qq_41809823的博客 723

Socket网络编程:TCP与UDP

socket网络编程:TCP与UDP

Edward2022的博客 8918

YOLOv11魔改高效涨点 | 注意力篇 | SimAM注意力:基于神经科学的 3D 注意力机制,三维权重的暴力美学,无参数也能暴力涨点?代码极简,彻底疯狂!!!

在本文中,我们为卷积神经网络(ConvNets)提出了一个概念简单但非常有效的注意力模块。与现有的通道注意力(Channel-wise)和空间注意力(Spatial-wise)模块不同,我们的模块在不向原始网络添加参数的情况下,推断出层中特征图的 3D 注意力权重。具体来说,我们基于一些知名的神经科学理论,提出优化一个能量函数来寻找每个神经元的重要性。我们进一步推导出了该能量函数的快速闭式解,并表明该解可以用不到十行代码实现。

猫天意的博客 248

Linux epoll与socket

epoll 是 Linux 提供的一种高效的 I/O 多路复用接口,它是 select 和 poll 的增强版,用于同时监视多个文件描述符(FDs),以确定哪些 FDs 已经准备好进行 I/O 操作。epoll 相较于 select 和 poll 更加高效,因为它不需要在每次调用时重复传递和检查整个文件描述符集合,而是通过事件回调机制来通知进程哪些 FDs 已经就绪。

fukaiqiang 923

Codex 100个真实案例 - 用AI自动生成API测试用例(接口测试全覆盖)

API 测试是保障后端质量的关键环节,但手写测试用例既枯燥又容易遗漏。本案例将展示如何用 Codex 从 Swagger/OpenAPI 规范文档自动生成 pytest 测试用例——包括正常流程测试、边界值测试、异常参数测试、性能压力测试,还能自动生成 Mock 数据和精美的 HTML 测试报告。全程自然语言驱动,让 API 测试覆盖率从 0 飙到 90%+!

yueyeguzhuo的专栏 270

SAP物料主数据中的销售视图。这是一个在销售与分销模块中至关重要的核心主数据,直接关系到从报价到交货的整个销售流程

SAP物料主数据的销售视图是销售流程的核心基础,它定义了物料如何被销售、定价、开票和交付。销售视图包含五个关键控制点:1)基本销售数据控制物料销售状态;2)销售组织数据决定销售渠道和产品分类;3)通用物料数据管理销售描述和税务分类;4)交货计划控制交付参数;5)开票计划管理定价规则。这些设置直接影响销售流程顺畅度、数据准确性、客户满意度、财务合规性和业务灵活性。建议将销售视图创建纳入新产品引入流程,并建立规范的维护机制,确保业务变化时及时更新配置。

金牌架构师 666

I/O多路复用之epoll模型、触发模式

【代码】I/O多路复用之epoll模型、触发模式。

asdzccfrew的博客 796

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

WebServer代码解读(2)【初始化server socket】【设置epoll事件】【注册描述符】【封装epoll_wait】

文章目录1 - server socketsocket创建、绑定、监听关于listen函数设置监听socket为非阻塞2 - 设置epoll事件epoll事件类型水平触发与边沿触发3 - 注册新描述符4 - 等待事件发生 1 - server socket 首先要创建server端的socket(socket函数),绑定端口(bind函数),开始监听(listen函数) 绑定端口时注意,0-1023为知名端口号范围,能够bind的端口限制在1024-65535之间 还要注意绑定的端口如果被占用(Addre

日月既往,不可复追 637

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C++ TCP Socket服务端开发:从基础API到高并发epoll实战

网络通信是分布式系统和现代应用开发的基石,而TCP协议作为可靠传输的核心,其Socket编程是每位C++开发者必须掌握的底层技能。理解Socket的本质是网络通信的端点,通过文件描述符进行读写操作,是深入操作系统网络栈的关键。从单线程阻塞模型到多线程/多进程架构,再到基于epoll的I/O多路复用技术,服务端设计的演进直接决定了系统的并发处理能力和资源效率。在实际工程中,正确处理字节序转换、粘包拆包、连接优雅关闭等细节,结合Wireshark等工具进行网络抓包分析,是构建健壮服务的保障。本文通过完整代码示例

weixin_33924312的博客 505

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

epoll边缘触发_echo-epoll/epoll边缘触发与水平触发.md at master · superLish/echo-epoll · GitHub...

在网络编程中,会涉及到水平触发与边缘触发的概念,工程中以边缘触发较为常见,本文讲述了边缘触发与水平触发的概念,并给出代码示例,通过代码可以很清楚的看到它们之间的区别。水平触发与边缘触发水平触发(level-trggered)只要文件描述符关联的读内核缓冲区非空,有数据可以读取,就一直发出可读信号进行通知,当文件描述符关联的内核写缓冲区不满,有空间可以写入,就一直发出可写信号进行通知边缘触发(edg...

weixin_31921223的博客 234

socket_epoll

title: socket_log date: 2016-07-10 15:55:17tags: socket1.介绍重要的socket()函数1.1.socket():返回一个文件描述符实际上所有的读取都是通过文件描述符来进行读取,文件描述符表示一个进程与打开文件之间对应关系, 使用int 唯一标识文件,下次进行读取的时候也通过打开文件时候返回的文件标识符进行读取!网络读取也会是一样的! 1

yan04_30的博客 471

Linux C语言TCP网络编程实战:从Socket到epoll并发服务器

网络编程是现代软件开发的基石,其核心在于实现不同主机间进程的可靠通信。TCP协议通过三次握手建立连接、四次挥手断开连接,并利用序列号、确认应答和重传机制,确保了数据传输的可靠性与顺序性。这一技术价值在于为上层应用提供了稳定的字节流传输服务,是构建Web服务器、即时通讯、分布式系统等高性能网络应用的基础。在实际工程中,开发者通过操作系统提供的Socket API进行编程,需要处理地址绑定、端口监听、连接建立、数据收发以及资源释放等关键步骤。针对高并发场景,I/O多路复用技术如epoll模型成为提升服务器性能的

weixin_30325487的博客 945

【Linux】使用 epoll 实现 异步IO 多路复用

坑解决方案ET 模式只读一次,剩下数据再也收不到必须= EAGAIN)循环读空ET 模式用阻塞 fd 卡死ET 必须配合O_NONBLOCKeventfd 写完不读,CPU 100% 空转里必须 read 清空计数器close(fd)后忘记一般 close 自动移除,但 fd 被 dup 过时需要手动删信号中断导致epoll_wait返回 -1检查后 continue多线程同时操作同一个 epoll fdepoll 本身线程安全,但要注意事件分发的竞争EPOLLOUT。

嵌入式、机器人、深度学习 486

TKeed源码分析之添加listen监听事件

前面初始化监听套接字listen_fd后,现在把它加入到epoll内核事件表当中。 // 初始化套接字开始监听 int listen_fd = socket_bind_listen(conf.port); // 设置为socket非阻塞 int rc = make_socket_non_blocking(listen_fd); // 创建epoll并注册监听...

qq_36415932的博客 408

【Linux网络】多路转接epoll(一):epoll理论 + 编写v1版本代码

在 Linux IO 多路转接技术体系中,select与poll受限于内核轮询遍历、数据拷贝、文件描述符集合维护等性能瓶颈,无法支撑海量并发场景。epoll作为 Linux 内核专属的高性能多路转接方案,在 2.5.44 版本内核正式推出,重构了事件监听与就绪通知的底层逻辑,依托红黑树、就绪队列与内核回调机制,彻底解决了前代方案的性能缺陷,成为 Linux 平台高并发网络服务的首选技术。本文将从诞生背景、核心 API、内核底层原理、事件模式、完整代码实战、问题分析等维度,系统性梳理epoll。

艾莉丝努力练剑的博客,感谢大家一直以来的对艾莉丝的支持和鼓励,uu们如果对C/C++方向感兴趣的话,可以通过艾莉丝主页的微信名片加艾莉丝的好友,和努力练剑的艾莉丝一起加油! 1242

epoll介绍与TCP服务器实战

本文介绍了Linux中的epoll机制及其在网络编程中的应用。epoll是一种高效的IO多路复用技术,相比select/poll具有显著优势:采用红黑树管理兴趣列表,双向链表管理就绪列表;能直接返回就绪事件;支持边沿触发模式。文章详细解析了epoll相关函数(epoll_create/ctl/wait)和事件类型,比较了水平触发(LT)和边沿触发(ET)的区别。最后通过一个TCP服务器实现示例,展示了如何利用epoll同时监听多个端口,处理连接请求和数据接收,其中监听套接字采用边沿触发模式,客户端套接字采用

GentalYuan的博客 348
上一篇: DNS Query Flood攻击
下一篇: 硬盘安装Centos7可能遇到的一些问题
Virgilio
博客等级 码龄17年 33粉丝 22原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值