day4 多路复用epoll函数族

您所在的位置:网站首页 C语言利用epoll实现高并发聊天室 day4 多路复用epoll函数族

day4 多路复用epoll函数族

2023-06-02 12:59| 来源: 网络整理| 查看: 265

目录

epoll函数族介绍

epoll_event结构体

epoll服务期实现

server.c

select,poll和epoll各自优缺点

select

poll

epoll

epoll函数族介绍 /*创建epoll句柄*/ int epoll_create(int size); //size参数实际上已经被弃用 /*epoll句柄的控制接口*/ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

 参数:

epfd: epoll 专用的文件描述符,epoll_create()的返回值

op: 表示动作,用三个宏来表示:

        EPOLL_CTL_ADD:注册新的 fd 到 epfd 中;

        EPOLL_CTL_MOD:修改已经注册的fd的监听事件;

         EPOLL_CTL_DEL:从 epfd 中删除一个 fd;

fd: 需要监听的文件描述符

event: 告诉内核要监听什么事件

epoll_event结构体 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 */ };

EPOLLIN :表示对应的文件描述符可以读(包括对端 SOCKET 正常关闭);

EPOLLOUT:表示对应的文件描述符可以写;

EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);

EPOLLERR:表示对应的文件描述符发生错误;

EPOLLHUP:表示对应的文件描述符被挂断;

EPOLLET :将 EPOLL 设为边缘触发(Edge Trigger)模式,这是相对于水平触发(Level Trigger)来说的。

EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个 socket 的话,需要再次把这个 socket 加入到 EPOLL 队列里  

/*等待 epoll 文件描述符上的 I/O 事件*/ int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

 参数:

epfd: epoll 专用的文件描述符,epoll_create()的返回值

events: 分配好的 epoll_event 结构体数组,epoll_wait 将会把发生的事件赋值到events 数组中

maxevents: events 数组的元素个数

timeout: 超时时间,单位为毫秒,为 -1 时,函数为阻塞  

epoll服务期实现 server.c #include "net.h" #include #define MAX_SOCK_FD 1024 int main(int argc, char *argv[]) { int i, nfds, fd, epfd, newfd; Addr_in addr; socklen_t addrlen = sizeof(Addr_in); struct epoll_event tmp, events[MAX_SOCK_FD] = {}; /*检查参数,小于3个 直接退出进程*/ Argment(argc, argv); /*创建已设置监听模式的套接字*/ fd = CreateSocket(argv); if( (epfd = epoll_create(1)) < 0) ErrExit("epoll_create"); tmp.events = EPOLLIN; tmp.data.fd = fd; if( epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &tmp) ) ErrExit("epoll_ctl"); while(1) { if( (nfds = epoll_wait(epfd, events, MAX_SOCK_FD, -1) ) < 0) ErrExit("epoll_wait"); printf("nfds = %d\n", nfds); for(i = 0; i < nfds; i++) { if(events[i].data.fd == fd){ /*接收客户端连接,并生成新的文件描述符*/ if( (newfd = accept(fd, (Addr *)&addr, &addrlen) ) < 0) perror("accept"); printf("[%s:%d] connection.\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port) ); tmp.events = EPOLLIN; tmp.data.fd = newfd; if( epoll_ctl(epfd, EPOLL_CTL_ADD, newfd, &tmp) ) ErrExit("epoll_ctl"); }else{/*处理客户端数据*/ if(DataHandle(events[i].data.fd)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3