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代码讲解 最后 源代码 ...
随机推荐
- Ubuntu 13.10 下安装搜狗输入法
1.卸载ibus输入法: sudo apt-get remove ibus sudo为取得root权限的意思,Ubuntu系统默认root账户关闭,很多操作需要取得root 权限才可以 ...
- [Linux] 特殊文件 /dev/zero
/dev/zero 是类 Unix 系统中一个特殊的文件,当读取该文件时,它会提供无限的空字符 null.它的一个主要用途是提供字符流来初始化数据存储,也就是使用空字符覆盖目标数据.另一个常见的用法是 ...
- 在taro中跳转页面的时候执行两遍componentDidMount周期的原因和解决方法
在做taro跳转的时候,发现在跳转后的页面会走两遍componentDidMount周期,查看了github上的issues,发现是跳转路由带参为中文引起的,只要把中文参数进行urlencode解决 ...
- mysql在命令行模式下创建数据库时要显式指定字符集
create database db1 DEFAULT CHARACTER SET utf8 COLLATE utf8_chinese_ci;
- thinkphp5.0 实现单文件上传功能
思路是:在app/ceshi/fire下面有一个index操作方法来渲染显示前端文件,然后前端文件跳转到upload操作方法进行处理,成功显示"文件上传成功",失败显示错误. 首先 ...
- 【MySQL】 Cannot load from mysql.proc. The table is probably corrupted
解决办法 在 mysql 这张表里边.执行sql ALTER TABLE `proc` MODIFY COLUMN `comment` text CHARACTER SET utf8 COLLATE ...
- vue案例 - v-model实现自定义样式の多选与单选
接,上文:https://www.cnblogs.com/padding1015/p/9265985.html 这两天在玩mpvue,但是下午如果对着文档大眼瞪小眼的话,肯定会睡着的. 想起昨晚的fl ...
- Android Studio 3.1.2 版本包下载
Android Studio 3.1.2 bug 修复版已发布,本次更新修复了一些错误,并改进了某些场景下 lint 审查的速度.详细的修复内容请查看 Android Studio 3.1.2 的发布 ...
- 【Studio】解决格式化时,注释部分没有缩进的问题
android studio默认代码格式化(默认Ctrl+Alt+L),是让注释从每行最左边开始显示,比如这样: 我个人喜欢注释也要缩进对齐.其实这个需要自己设置,打开studio的设置,依次找 Se ...
- MySQL里面的子查询
一.子查询定义 定义: 子查询允许把一个查询嵌套在另一个查询当中. 子查询,又叫内部查询,相对于内部查询,包含内部查询的就称为外部查询. 子查询可以包含普通select可以包括的任何子句,比如:dis ...