- 浏览: 182322 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
grzrt:
zkf55915 写道哥们怎么用啊
好久不用了,就是看帮助资 ...
淘宝MetaQ开源消息队列安装 -
zkf55915:
哥们怎么用啊
淘宝MetaQ开源消息队列安装 -
grzrt:
jinnianshilongnian 写道整这个了?
没有 看 ...
linux内核中链表的实现 -
jinnianshilongnian:
整这个了?
linux内核中链表的实现
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) } } } }
发表评论
-
使用pidstat查看进程资源使用情况
2013-03-12 11:06 4507在查看系统资源使用情况时,很多工具为我们提供了从设备角度查 ... -
Eclipse 相同变量的高亮 及颜色
2013-02-18 17:26 1582在Eclipse/MyEclipse中如果不小心把变量的高 ... -
copy项目是容易出现的错误--webAppRootKey错误
2012-12-05 21:18 683Tomcat 发布多个项目时抛的webAppRootKey错误 ... -
redis主从的配置和使用
2012-11-23 14:24 997redis主从的配置和使 ... -
小议同步IO :fsync与fdatasync
2012-09-13 20:23 683对于提供事务支持的 ... -
Linux修改MySql默认存储引擎为InnoDB
2012-09-13 18:25 1529一、关闭相关应用 二、停止mysql bin/m ... -
MySQL数据库的初始化mysql_install_db
2012-09-13 14:13 4645一、mysql_install_db说明 当MySQL的 ... -
四层和七层负载均衡的区别介绍
2012-09-12 11:46 800简单理解四层和七层负载均衡:①所谓四层就是基于IP+端口 ... -
Linux下高并发Tcp需要突破的限制
2012-09-06 13:47 7161、修改用户进程可打开文件数限制 在Linux平台上, ... -
LInux Tcp 延迟确认问题
2012-09-06 10:17 1351案例一:同事随手写个压力测试程序,其实现逻辑为:每秒钟先连续发 ... -
Linux tcpdump命令详解
2012-09-06 10:00 1024简介 用简单的话来定义tcpdump,就是:dum ... -
Nagle算法 TCP_NODELAY和TCP_CORK
2012-09-06 08:43 1166Nagle算法 根据创建者John Nagle命 ... -
Oracle之自治事务
2012-09-04 11:32 967昨天处理项目中的一个 ... -
socket中accept()函数的理解
2012-09-01 22:41 6750如果客户端有连接请 ... -
Linux sar 分析网卡流量
2012-08-23 11:39 1296yum install sysstatsar -n { DEV ... -
mysql 主从复制1201错误
2012-08-19 15:59 892工作日志之-MySQL slave Replication E ... -
Redis学习手册(主从复制)
2012-08-19 11:39 769一、Redis的Replication: 这里首先需要说 ... -
Redis学习手册(持久化)
2012-08-19 11:39 738一、Redis提供了哪些持久化机制: 1). RDB持久 ... -
Redis学习手册(虚拟内存)
2012-08-19 11:38 696一、简介: 和大多NoS ... -
socket中的TIME_WAIT状态
2012-08-16 11:47 716TCP要保证在所有可能的 ...
相关推荐
epoll用到的所有函数都是在头文件sys/epoll.h中声明的,本文简要说明所用到的数据结构和函数。
linux socket tcp epoll使用教程 例子 源代码
Linux下通过epoll机制进行串口监听,当收到数据时,通过tcp进行数据转发给服务器
linux系统下,利用epoll接收串口助手发来的数据并打印。
linux下epoll示例程序 服务器端 客服端 实现多人聊天
linux下的epoll服务程序及客户端实例,服务程序支持多连接,并能稳定进行数据传输。
Linux下基于epoll_线程池高并发服务器实现研究,研究Linux的人可以看看。
epoll在内核版本2.6以上才出现的新的函数,而他们在linux内核中的实现都是十分相似。 这三种函数都需要设备驱动提供poll回调函数,对于套接字而言,他们是 tcp_poll,udp_poll和datagram_poll; 对于自己开发的设备...
Windows完成端口介绍 Linux EPOLL介绍 同步I/O与异步I/O 说起完成端口,它的实现机制其实是重叠I/O实现异步I/O操作,下面就结合同步I/O来解释下什么是异步I/O
但是一直到2.6内核发布,网络模块的AIO一直没有进入稳定内核版本(大部分都是使用用户线程模拟方法,在使用了NPTL的linux上面其实和windows的完成端口基本上差不多了)。2.6内核所支持的AIO特指磁盘的AIO---支持io_...
linux 网络编程 epoll 简单示例 客户端 源码 只为学习epoll用 有不妥之处欢迎指正
linux下epoll网络模型介绍 简单讲解如何使用epoll模型, linux下epoll网络模型介绍 简单讲解如何使用epoll模型
一个Linux下对epoll封装的类,方便初学者
大并发服务器编程模型 windows iocp完成端口模型可支持1万大并发,但是linux能作到5万大并发
linux epoll 例子程序
linux 通过 epoll 实现 tcp 服务器 代码
linux中 epoll poll 和select的区别
本程序以简单的例子介绍了Linux中epoll的用法
linux 网络编程 epoll 简单示例 服务端 只为学习用 有不妥之处欢迎指正
linux epoll 服务器,windows socket客户端