关于epoll 水平触发在udp套接字上不生效问题的原因

相关知识点简介: epoll有两个模式可以设置,一个是水平模式(level-triggered),另一个是边缘模式(edge-triggered), 区别就是水平模式可以带来事件的重复触发,而边缘模式只触发一次。举个栗子,当epoll监听的描述符发生可读事件时,比方说收到了别人发来的10个字节数据,你只读了一个字节,如果是水平触发,那么epoll将一直触发直到剩下那9个字节读完,而边缘触发呢,就是收到了一个读事件,你自己去读吧,读多少算多少,而epolll只触发一次。

而我在实际测试epoll监听udp套接字的时候,使用默认的水平触发去监听读事件,每次只读取一个字节,按道理收到多个字节epoll应该触发(trigger)多次才对,结果它只触发了一次,如图:


程序启动后监听3500端口,使用网络调试助手发3个字节到监听地址,只读取一个,结果显示epoll触发一次后就hang住

代码这样写的:

    while(1) {
        fds = epoll_wait(efd, epoll_events_ptr, 2, -1); //阻塞
        for (i = 0; i<fds; i++)
        {    
            if (epoll_events_ptr[i].events & EPOLLIN)
            {   
                ret = read(fd1, buffer, 1);
                if(ret != -1)
                    log("recv msg : %s \n", buffer);
                }     
            memset(buffer, 0, BUFFER_SIZE);
        }        
    }   

同样情况下,如果监听的是标准输入的话,epoll触发了多次,如下图,代码就不贴了


两个例子流程基本一样,除了一个监听udp套接字,一个监听标准输入(STDIN_FILENO)

最后在stackoverflow上有大神解答说UDP套接字是以报文为单位的,如果一次没有读取完成,剩余数据会被丢弃,这解释了为什么epoll只触发了一次,因为在读取一个字节的时候,剩余两个字节被丢弃了。这和面向字节流的TCP套接字不同。

stackoverflow上的问题链接

https://stackoverflow.com/questions/50938689/epoll-eventsepolllt-only-triggered-once-on-udp-socket/50939267#50939267

创建了一个linux应用&内核相关开发到讨论群:745510310 欢迎有兴趣的同学加入大笑


                
### 回答1: epoll 可以同时监听服务器套接字和连接套接字,具体取决于注册的文件描述符类型。当 epoll 实例被创建时,需要选择一个 epoll 事件模型,可以是 LT(Level-Triggered)或 ET(Edge-Triggered)。在 LT 模式下,epoll 监听到文件描述符上的事件时,会一直通知应用程序,直到应用程序处理完该事件。而在 ET 模式下,epoll 只会在文件描述符上发生状态变化时通知应用程序,应用程序需要立即处理该事件,否则可能会错过该事件。因此,对于连接套接字,如果使用 ET 模式,可以提高处理效率。 ### 回答2: epoll是一种在Linux系统中用于高效网络编程的I/O多路复用机制。它可以同时监听多个套接字上的事件,并且只有当有事件发生时才返回给应用程序。 具体来说,epoll监听的是连接套接字(也称为文件描述符),而不是服务器套接字。 首先,服务器套接字是通过调用`socket()`函数创建的,用于监听客户端的连接请求。服务器套接字处于监听状态,并且可以接受多个客户端的连接请求。 而连接套接字是在服务器套接字接受一个客户端连接后创建的,用于与该客户端进行通信。每当有新的客户端连接时,服务器会创建一个新的连接套接字,并将其添加到epoll的事件集合中。 在使用epoll时,我们要将连接套接字添加到epoll的事件集合中,并设置相应的事件(如读事件、写事件)。当有事件发生时,epoll会通过返回就绪的事件以及相应的连接套接字,告知应用程序哪些套接字上发生了事件,然后应用程序可以进行相应的处理,如读取数据或发送数据。 总结起来,epoll监听的是连接套接字,用于处理网络事件。服务器套接字只负责接受连接请求,并没有与epoll直接关联。 ### 回答3: epoll 是一种 I/O 多路复用机制,它可以用于监听套接字上的事件。在 Linux 操作系统中,epoll 可以同时监控多个事件,例如新连接的到达、数据的可读和可写等。 通常情况下,epoll 主要用于监听服务器套接字,也就是服务器用于接受客户端连接的套接字。当有新的客户端连接到服务器时,epoll 将会通知服务器去接受该连接。 在接受了客户端的连接之后,服务器会为每个连接创建一个连接套接字,该连接套接字用于与客户端进行数据的读写。以 epoll 监听连接套接字并处理数据通信的操作是可以的,但一般情况下更常见的是使用 epoll 监听服务器套接字,并在有新的连接到来时,将连接套接字添加到 epoll 的监听列表中。 因此,epoll 监听的主要是服务器套接字,用于接受新的客户端连接并处理数据通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值