`

epoll模型

阅读更多
epoll用到的所有函数都是在头文件sys/epoll.h中声明的,下面简要说明所用到的数据结构和函数:
所用到的数据结构
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 */
};
结构体epoll_event 被用于注册所感兴趣的事件和回传所发生待处理的事件,其中epoll_data 联合体用来保存触发事件的某个文件描述符相关的数据,例如一个client连接到服务器,服务器通过调用accept函数可以得到于这个client对应的socket文件描述符,可以把这文件描述符赋给epoll_data的fd字段以便后面的读写操作在这个文件描述符上进行。epoll_event 结构体的events字段是表示感兴趣的事件和被触发的事件可能的取值为:EPOLLIN :表示对应的文件描述符可以读;
EPOLLOUT:表示对应的文件描述符可以写;
EPOLLPRI:表示对应的文件描述符有紧急的数据可读(我不太明白是什么意思,可能是类似client关闭 socket连接这样的事件);
EPOLLERR:表示对应的文件描述符发生错误;
EPOLLHUP:表示对应的文件描述符被挂断;
EPOLLET:表示对应的文件描述符有事件发生;
所用到的函数:
1、epoll_create函数
函数声明:int epoll_create(int size)
该函数生成一个epoll专用的文件描述符,其中的参数是指定生成描述符的最大范围(我觉得这个参数和select函数的第一个参数应该是类似的但是该怎么设置才好,我也不太清楚)。
2、epoll_ctl函数
函数声明:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
该函数用于控制某个文件描述符上的事件,可以注册事件,修改事件,删除事件。
参数:epfd:由 epoll_create 生成的epoll专用的文件描述符;
op:要进行的操作例如注册事件,可能的取值EPOLL_CTL_ADD 注册、EPOLL_CTL_MOD 修
改、EPOLL_CTL_DEL 删除
fd:关联的文件描述符;
event:指向epoll_event的指针;
如果调用成功返回0,不成功返回-1
3、epoll_wait函数
函数声明:int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout)
该函数用于轮询I/O事件的发生;
参数:
epfd:由epoll_create 生成的epoll专用的文件描述符;
epoll_event:用于回传代处理事件的数组;
maxevents:每次能处理的事件数;
timeout:等待I/O事件发生的超时值;
返回发生事件数。
例子:







代码:


#include <iostream>

#include <sys/socket.h>

#include <sys/epoll.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>



#define MAXLINE 10

#define OPEN_MAX 100

#define LISTENQ 20

#define SERV_PORT 5555

#define INFTIM 1000



void setnonblocking(int sock)

{

int opts;

opts=fcntl(sock,F_GETFL);

if(opts<0)

{

perror("fcntl(sock,GETFL)");

exit(1);

}

opts = opts|O_NONBLOCK;

if(fcntl(sock,F_SETFL,opts)<0)

{

perror("fcntl(sock,SETFL,opts)");

exit(1);

}

}



int main()

{

int i, maxi, listenfd, connfd, sockfd,epfd,nfds;

ssize_t n;

char line[MAXLINE];

socklen_t clilen;

//声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件

struct epoll_event ev,events[20];

//生成用于处理accept的epoll专用的文件描述符

epfd=epoll_create(256);



struct sockaddr_in clientaddr;

struct sockaddr_in serveraddr;

listenfd = socket(AF_INET, SOCK_STREAM, 0);

//把socket设置为非阻塞方式

setnonblocking(listenfd);

//设置与要处理的事件相关的文件描述符

ev.data.fd=listenfd;

//设置要处理的事件类型

ev.events=EPOLLIN|EPOLLET;

//注册epoll事件

epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);



bzero(&serveraddr, sizeof(serveraddr));

serveraddr.sin_family = AF_INET;



char *local_addr="200.200.200.204";

inet_aton(local_addr,&(serveraddr.sin_addr));//htons(SERV_PORT);

serveraddr.sin_port=htons(SERV_PORT);

bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr));

listen(listenfd, LISTENQ);



maxi = 0;

for ( ; ; ) {

//等待epoll事件的发生

nfds=epoll_wait(epfd,events,20,500);

//处理所发生的所有事件

for(i=0;i<nfds;++i)

{

if(events[i].data.fd==listenfd)

{



connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen);

if(connfd<0){

perror("connfd<0");

exit(1);

}

setnonblocking(connfd);



char *str = inet_ntoa(clientaddr.sin_addr);

std::cout<<"connect from "<_u115 ?tr<<std::endl;

//设置用于读操作的文件描述符

ev.data.fd=connfd;

//设置用于注测的读操作事件

ev.events=EPOLLIN|EPOLLET;

//注册ev

epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);

}

else if(events[i].events&EPOLLIN)

{

if ( (sockfd = events[i].data.fd) < 0) continue;

if ( (n = read(sockfd, line, MAXLINE)) < 0) {

if (errno == ECONNRESET) {



close(sockfd);

events[i].data.fd = -1;

} else

std::cout<<"readline error"<<std::endl;

} else if (n == 0) {

close(sockfd);

events[i].data.fd = -1;

}

//设置用于写操作的文件描述符

ev.data.fd=sockfd;

//设置用于注测的写操作事件

ev.events=EPOLLOUT|EPOLLET;

//修改sockfd上要处理的事件为EPOLLOUT

epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);

}

else if(events[i].events&EPOLLOUT)

{

sockfd = events[i].data.fd;

write(sockfd, line, n);

//设置用于读操作的文件描述符

ev.data.fd=sockfd;

//设置用于注测的读操作事件

ev.events=EPOLLIN|EPOLLET;

//修改sockfd上要处理的事件为EPOLIN

epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
}
}
}
}
分享到:
评论

相关推荐

    Epoll模型详解

    ### Epoll模型详解 #### 一、Epoll概述 在Linux网络编程中,早期广泛使用的事件触发机制主要是基于`select`。然而随着技术的发展以及应用需求的提高,`select`逐渐暴露出了一些明显的局限性,比如它对于大量文件...

    epoll模型的一个例子

    `epoll`模型是解决高并发服务器性能瓶颈的有效手段之一,它比传统的`select`和`poll`模型更加先进,能够更有效地管理和监控文件描述符(FDs)的状态变化。 `epoll`的核心概念包括`epoll_create`、`epoll_ctl`和`...

    网络编程epoll模型

    网络编程中的`epoll`模型是Linux操作系统提供的一种高效、高性能的I/O多路复用技术,主要用于管理和调度大量的并发连接。在这个模型中,`epoll`替代了传统的`select`和`poll`,解决了它们在处理大量文件描述符时性能...

    Linux网络通信epoll模型

    epoll模型作为Linux提供的一种I/O多路复用技术,正是为了解决这一问题而设计的。本文将深入探讨epoll的工作原理、优势以及如何在实际编程中运用。 epoll,全称Event Poll,它是基于文件描述符(file descriptor)的...

    epoll_loop.c epoll模型反应堆

    epoll反应堆模型代码,相对于网上普通的epoll模型增加了send recv 操作,并有详细的注释epoll反应堆

    http server&client;(epoll模型)

    接下来,我们讨论epoll模型。epoll是Linux系统提供的一种高效I/O事件通知机制,尤其适用于高并发的网络服务器。它替代了传统的select和poll,解决了它们在大量文件描述符时性能下降的问题。epoll通过内核用户空间...

    linux下Epoll模型实例代码

    Epoll模型相比传统的select、poll等I/O多路复用模型,具有更好的性能和可扩展性。这个"linux下Epoll模型实例代码"是一个展示如何在Linux环境下使用Epoll进行I/O事件监控的程序示例。 Epoll的核心概念包括以下几个...

    epoll模型 http server

    epoll模型http server

    Epoll模型详解借鉴.pdf

    《Epoll模型详解》 在Linux的网络编程领域,Epoll模型是替代传统select模型的一种高效解决方案。Epoll的优势在于其高效性和可扩展性,它避免了随着监听文件描述符(fd)数量增加而导致的性能下降问题。传统的select...

    Epoll模型[借鉴].pdf

    《深入理解Epoll模型在Linux网络编程中的应用》 在Linux的网络编程中,Epoll模型作为select模型的替代方案,具有显著的性能优势。Epoll的出现解决了select在面对大量文件描述符(FD)时效率低下的问题,它通过高效...

    Epoll模型详解.pdf

    《Epoll模型详解》 Epoll是Linux内核提供的一种高效、可扩展的I/O事件通知机制,尤其在处理大量并发连接时表现出显著优势。它替代了传统的select和poll方法,解决了这些方法在处理大量文件描述符(fd)时效率低下的...

    EPOLL模型:关于并发连接的处理

    ### EPOLL模型:关于并发连接的处理 #### 一、Select 的局限性 在 Linux 内核中,`select` 是一种常用的 I/O 多路复用机制,它允许一个进程监控多个文件描述符(FD),并在这些 FD 就绪(例如可读或可写)时通知...

    (二)Linux Epoll模型.mmap

    用思维导图的方式总结了Epoll模型,非常的好理解。文件需要用MindMange打开。

    epoll网络模型

    2. **EPOLL模型**:在`epoll`中,主要有三个关键函数:`epoll_create`、`epoll_ctl`和`epoll_wait`。 - `epoll_create`:创建一个`epoll`实例,返回一个描述符。 - `epoll_ctl`:用于管理和修改`epoll`实例中的...

    Android Epoll模型

    在Android系统中,Epoll模型是一种高效的I/O多路复用技术,主要用于处理大量的并发连接。JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。当我们需要在Android应用...

    EPOLL模型详解

    **EPOLL模型详解** Linux 2.6内核引入了EPOLL模型,作为解决I/O多路复用问题的一种高效机制,特别是在处理大量socket描述符(FD)时。EPOLL对比传统的select和poll模型,具有以下显著优点: 1. **不受FD数量限制**...

    linux epoll模型

    Linux下的epoll模型是高效处理I/O事件的一种机制,尤其在高并发的网络服务中表现卓越。epoll是由早期的poll和select模型发展而来,它提供了更优秀的性能和可扩展性。在这里,我们有两个示例服务器模型:mychat和...

    linux下服务器的搭建,socket+epoll模型+线程池+心跳检测+工厂模式;内含客户端的测试

    本教程将深入探讨如何利用socket编程、epoll模型、线程池、心跳检测以及工厂模式来搭建这样的服务器,并且提供了客户端的测试代码。以下是对这些知识点的详细解释: 1. **Linux Socket编程**: Linux Socket是进程...

    epoll模型异步通信JSON服务器servermyserver.zip

    myserver是一个基于epoll模型的异步通信、返回结果为JSON的高性能服务器。它使用C 编写,需要通过mylog以及myconf这二者做编译依赖。和外界交互为JSON格式(使用开源库rapidjson)。用户只需要配置好服务器,开始...

Global site tag (gtag.js) - Google Analytics