Linux IO模式及 select、poll、epoll详解及源码(转)
原文:https://segmentfault.com/a/1190000003063859
我只摘取了其中的epoll代码示例,服务端代码
#define IPADDRESS "127.0.0.1"
#define PORT 8787
#define MAXSIZE 1024
#define LISTENQ 5
#define FDSIZE 1000
#define EPOLLEVENTS 100 listenfd = socket_bind(IPADDRESS,PORT); struct epoll_event events[EPOLLEVENTS]; //创建一个描述符
epollfd = epoll_create(FDSIZE); //添加监听描述符事件
add_event(epollfd,listenfd,EPOLLIN); //循环等待
for ( ; ; ){
//该函数返回已经准备好的描述符事件数目
ret = epoll_wait(epollfd,events,EPOLLEVENTS,-);
//处理接收到的连接
handle_events(epollfd,events,ret,listenfd,buf);
} //事件处理函数
static void handle_events(int epollfd,struct epoll_event *events,int num,int listenfd,char *buf)
{
int i;
int fd;
//进行遍历;这里只要遍历已经准备好的io事件。num并不是当初epoll_create时的FDSIZE。
for (i = ;i < num;i++)
{
fd = events[i].data.fd;
//根据描述符的类型和事件类型进行处理
if ((fd == listenfd) &&(events[i].events & EPOLLIN))
handle_accpet(epollfd,listenfd);
else if (events[i].events & EPOLLIN)
do_read(epollfd,fd,buf);
else if (events[i].events & EPOLLOUT)
do_write(epollfd,fd,buf);
}
} //添加事件
static void add_event(int epollfd,int fd,int state){
struct epoll_event ev;
ev.events = state;
ev.data.fd = fd;
epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&ev);
} //处理接收到的连接。将文件描述符添加到epoll监控队列
static void handle_accpet(int epollfd,int listenfd){
int clifd;
struct sockaddr_in cliaddr;
socklen_t cliaddrlen;
clifd = accept(listenfd,(struct sockaddr*)&cliaddr,&cliaddrlen);
if (clifd == -)
perror("accpet error:");
else {
printf("accept a new client: %s:%d\n",inet_ntoa(cliaddr.sin_addr),cliaddr.sin_port); //添加一个客户描述符和事件
add_event(epollfd,clifd,EPOLLIN);
}
} //读处理
static void do_read(int epollfd,int fd,char *buf){
int nread;
nread = read(fd,buf,MAXSIZE);
if (nread == -) {
perror("read error:");
close(fd); //记住close fd
delete_event(epollfd,fd,EPOLLIN); //删除监听
}
else if (nread == ) {
fprintf(stderr,"client close.\n");
close(fd); //记住close fd
delete_event(epollfd,fd,EPOLLIN); //删除监听
}
else {
printf("read message is : %s",buf);
//修改描述符对应的事件,由读改为写
modify_event(epollfd,fd,EPOLLOUT);
}
} //写处理
static void do_write(int epollfd,int fd,char *buf) {
int nwrite;
nwrite = write(fd,buf,strlen(buf));
if (nwrite == -){
perror("write error:");
close(fd); //记住close fd
delete_event(epollfd,fd,EPOLLOUT); //删除监听
}else{
modify_event(epollfd,fd,EPOLLIN);
}
memset(buf,,MAXSIZE);
} //删除事件
static void delete_event(int epollfd,int fd,int state) {
struct epoll_event ev;
ev.events = state;
ev.data.fd = fd;
epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,&ev);
} //修改事件
static void modify_event(int epollfd,int fd,int state){
struct epoll_event ev;
ev.events = state;
ev.data.fd = fd;
epoll_ctl(epollfd,EPOLL_CTL_MOD,fd,&ev);
} //注:另外一端我就省了
Linux IO模式及 select、poll、epoll详解及源码(转)的更多相关文章
- Linux IO模式以及select poll epoll详解
一 背景 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network ...
- 文档-linux io模式及select,poll,epoll
文档-Linux IO模式详解 1. 概念说明 在进行解释之前,首先要说明几个概念:- 用户空间和内核空间- 进程切换- 进程的阻塞- 文件描述符- 缓存 I/O 1.1 用户空间与内核空间 现在操作 ...
- select用法&原理详解(源码剖析)(转)
今天遇到了在select()前后fd_set的变化问题,查了好久终于找到一个有用的帖子了,很赞,很详细!!原文链接如下: select用法&原理详解(源码剖析) 我的问题是: 如下图示:在se ...
- IO多路复用select/poll/epoll详解以及在Python中的应用
IO multiplexing(IO多路复用) IO多路复用,有些地方称之为event driven IO(事件驱动IO). 它的好处在于单个进程可以处理多个网络IO请求.select/epoll这两 ...
- Epoll详解及源码分析【转】
转自:http://blog.csdn.net/chen19870707/article/details/42525887 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] ...
- I/O模型之二:Linux IO模式及 select、poll、epoll详解
目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...
- Android应用AsyncTask处理机制详解及源码分析
1 背景 Android异步处理机制一直都是Android的一个核心,也是应用工程师面试的一个知识点.前面我们分析了Handler异步机制原理(不了解的可以阅读我的<Android异步消息处理机 ...
- 【转载】Android应用AsyncTask处理机制详解及源码分析
[工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处,尊重分享成果] 1 背景 Android异步处理机制一直都是Android的一个核心,也是应用工程师面试的一个 ...
- 基于双向BiLstm神经网络的中文分词详解及源码
基于双向BiLstm神经网络的中文分词详解及源码 基于双向BiLstm神经网络的中文分词详解及源码 1 标注序列 2 训练网络 3 Viterbi算法求解最优路径 4 keras代码讲解 最后 源代码 ...
随机推荐
- socket 中文man页面函数
Linux 套接字的用户接口. 这个 BSD 兼容套接字是介于用户进程与内核网络协议栈之间的统一接口, 各协议模块属于不同的 协议族 ,如 PF_INET, PF_IPX, PF_PACKET 和 套 ...
- C++ template —— 模板中的名称(三)
第9章 模板中的名称------------------------------------------------------------------------------------------ ...
- 在javaweb的项目当中实现随机数字的生成
首先,需要在javaweb的项目当中新建一个Servlet文件,然后再web.xml中配置一下: 这样运行的时候就可以通过“http://localhost:8080/Response/Respons ...
- Windows驱动中通过MDL实现用户态与核心态共享内存
Windows驱动跑在核心态(Kernel mode),驱动的调用者跑在用户态.如何使用户态进程与核心态驱动共享内存呢 ? 我们知道32位Windows中,默认状态下虚拟空间有4G,前2G是每个进程私 ...
- 机器学习实战-KNN
KNN算法很简单,大致的工作原理是:给定训练数据样本和标签,对于某测试的一个样本数据,选择距离其最近的k个训练样本,这k个训练样本中所属类别最多的类即为该测试样本的预测标签.简称kNN.通常k是不大于 ...
- 为什么WAN口IP和外网IP不一样(不一致)?
正常的网络应该是动态公网ip,也就是路由器里面的WAN口IP与www.ip138.com上面显示的是一致的,不一致的话则说明该网络被电信或者联通做了NAT转发,导致您获取到了一个虚假的IP地址,无法用 ...
- Qt编写视频播放器(vlc内核)
在研究qt+vlc的过程中,就想直接做个播放器用于独立的项目,vlc还支持硬件加速,不过部分电脑硬件不支持除外.用vlc的内核写播放器就是快,直接调用api就行,逻辑处理和ui展示基本上分分钟的事情, ...
- 三、K3 WISE 开发插件《K3 WISE开发手册》
1.VB插件工程的命名.命名空间和生成的DLL命名要一致,否则导致注册不成功! 2.主控台的查询分析工具,添加sql直接报表,代码用到临时表,提示“在对应所需名称或序数的集合中未找到项目” 解决:在代 ...
- 题目1091:棋盘游戏(DFS)
题目链接:http://ac.jobdu.com/problem.php?pid=1091 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...
- Openstack Nova network
对于安装设置来说,Openstack就剩下网络这个地方比较复杂. 现在比较喜欢看图 整理了一下网络的资料 1:Nova 网络HA http://unchainyourbrain.com/opensta ...