epoll:EPOLLET模式下的正确读写方式

本文探讨了EPOLLET(边缘触发)模式在Linux网络编程中的使用,强调了在EPOLLET模式下正确读写数据的重要性。不同于EPOLLLT(水平触发)模式,EPOLLET不需循环读取所有缓冲区数据。文章提醒,每次修改套接字事件时需重新设置EPOLLET,并提供了相关代码示例和epoll_event结构体的解析。
摘要由CSDN通过智能技术生成

1.EPOLLLT和EPOLLET最大的区别在于事件的通知机制,看这个文章EPOLLLT和EPOLLET的区别


2.EPOLLET模式下并不意味着要循环读取完缓冲区的所有数据,贴出一段读取代码:

n = 0;
while ((nread = read(fd, buf + n, BUFSIZ-1)) > 0) {
    n += nread;
}
if (nread == -1 && errno != EAGAIN) {
    perror("read error");
}
这段代码的陷阱在于,如果tcp缓冲区可读数据比buf大,那么将会造成堆栈溢出,所以循环读取缓冲区数据直到遇到EAGAIN并不是正确的做法。


3.需要注意的是,首次增加和每次修改套接字的events时,都需要指明EPOLLET,并不是ADD一次后就会永久是EPOLLET模式

    struct epoll_event ev;
    ev.events = EPOLLIN | EPOLLET; /* ET模式 */
    ev.data.fd = sockfd;
    if (-1 == epoll_ctl(efd, EPOLL_CTL_ADD, sockfd, &ev)) {
        perror("epoll_ctl EPOLL_CTL_ADD fail");
    }


4.EPOLLLT和EPOLLET在读取数据时的区别在于当数据没读取完毕,EPOLLET必须注册可读事件
5.EPOLLLT和EPOLLET在发送数据时的行为是一致的,都需要应用层主动判定是否有数据可发送

6.EPOLLLT模式下的正确读写方式


epoll_event结构体的理解

// man 2 epoll_ctl

typedef union epoll_data {
    void        *ptr;
    int          fd;
    __uint32_t   u32;
    __uint64_t   u64;
} epoll_data_t;

struct epoll_event {
    __uint32_t   events;      /* Epoll events */
    epoll_data_t data;        /* User data variable */
};


测试代码:

----- server.cpp -----

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

#define MAX_EVENTS 1000
#define MAX_LEN 1024

/*
参考 man epoll_ctl
EPOLLIN 可读
EPOLLOUT 可写
EPOLLPRI 紧急数据
EPOLLRDHUP 出错 
EPOLLERR 出错
EPOLLHUP 出错
*/

//设置非阻塞
static void setnonblocking(int sockfd) {
    int flag = fcntl(sockfd, F_GETFL, 0);
    if (flag < 0) {
        perror("fcntl F_GETFL fail");
        return;
    }
    if (fcntl(sockfd, F_SETFL, flag | O_NONBLOCK) < 0) {
       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值