unix网络编程str_cli使用epoll实现

unix环境高级编程中也有这个函数,都是为了讲解IO多路转接。从本质上来看epoll就是一个改善了的select和poll,本质没发生任何变化,对于构建在poll,select和epoll上的框架使用者来说,没什么区别。而对框架设计者来说,使用epoll来替换select或者poll代价也不大。

epoll说明

epoll主要涉及到三个函数,这个要比select和poll复杂,从本质上来说是因为epoll把通知内核我想要观察的描述符和内核通知我哪些描述符发生了变化分成了两个独立的部分,而前述的select和poll都是合二为一的,这也是为什么epoll能做到性能优势。

1.通知内核我想要观察哪些描述符

epoll_create

epollcreate用于创建一个文件描述符,以后所有的操作都与此文件描述符有关。实际上你可以认为这个相当于一个文件,存放了进程要观察的所有文件描述符集合。

原型是

int epoll_create(int size)

调用方式也很简单:

int epfd=epoll_create(10);

size 根据需要调整.

epoll_ctl 用于通知内核添加删除待观察文件描述符

epoll_ctl的使用比较复杂,主要是涉及到epoll_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 */
};

epoll_ctl的原型如下:

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

  • epfd 就是刚刚用epoll_create返回的描述符
  • op 是对文件描述符集合的操作,主要有增,删,改,没有查是因为这个是使用者自己维护的

    + EPOLL_CTL_ADD 增

    + EPOLL_CTL_MOD 改

    + EPOLL_CTL_DEL 删
  • fd 待增删改的文件描述符
  • event 这个是最复杂的数据结构也是我们关注的核心.这里我们只使用到了文件描述符的操作,其他说真的,我也不晓得用来做什么.

    + events是要观察文件描述符的哪些事件,主要有

    - EPOLLIN 可读

    - EPOLLOUT 可写

    - EPOLLERR 发生错误

    - EPOLLET 设置为边沿出发Edge Triggered, 类似于数电中的概念 ,如果不指定默认是水平触发Level Triggered

    - EPOLLONESHOT 只观察一次事件,一旦发生,对应的fd就会被内核从集合中删除

    - EPOLLPRI tcp 带外数据,用的很少

    - EPOLLHUP 对应的文件描述符被挂断,终端关闭事件.

    + data中的fd 设置为和epoll_ctl参数列表中的fd一致即可.

经过以上处理,内核已经知道了和epfd关联的待观察文件描述符集以及上面的事件.

等待关心事件的发生.

epoll_wait就是用来等待上述事件发生的,原型:int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout), epfd和epoll_ctl是一样的,events是内核返回给进程哪个文件描述符发生了什么事情,具体用法参考epoll_ctl。maxevents指明了events数组 大小;timeout可以指定超时,单位为毫秒(0会立即返回,-1是永久阻塞)。

unix网络编程中的str_cli函数

这个函数同时监听标准输入和一个连接到服务器的socket,如果用户输入了什么内容就会发送到服务器,如果从服务器收到了任何内容就直接输出到终端.


//
// Created by bai on 2/2/16.
// #include "../lib/unp.h" #include <sys/epoll.h> void str_cli(FILE *fp, int sockfd)
{
int efd;
struct epoll_event event;
struct epoll_event events[20];
int i;
int nfds;
char buf[MAXLINE];
int n; efd = epoll_create (10);
if(efd<0){
err_sys("epoll create failed");
}
event.data.fd=fileno(fp);
event.events=EPOLLIN;
epoll_ctl(efd,EPOLL_CTL_ADD,fileno(fp),&event); event.data.fd=sockfd;
event.events=EPOLLIN;
epoll_ctl(efd,EPOLL_CTL_ADD,sockfd,&event); for ( ; ; ) {
nfds=epoll_wait(efd,events,sizeof(events)/sizeof(struct epoll_event),-1);
if(nfds<0){
err_sys("epoll wait error %d ",errno);
}
for(i=0;i<nfds;i++){
if(events[i].data.fd==sockfd){
if ( (n = Read(sockfd, buf, MAXLINE)) == 0) {
err_quit("str_cli: server terminated prematurely");
}
Write(fileno(stdout), buf, n);
}
if(events[i].data.fd==fileno(fp)){
if ( (n = Read(fileno(fp), buf, MAXLINE)) == 0) {
close(sockfd);
break;
} Writen(sockfd, buf, n);
}
} }
close(efd);
}

unix网络编程str_cli使用epoll实现的更多相关文章

  1. unix网络编程 str_cli epoll 非阻塞版本

    unix网络编程 str_cli epoll 非阻塞版本 unix网络编程str_cli使用epoll实现讲了使用epoll配合阻塞io来实现str_cli,这个版本是配合非阻塞io. 可以看到采用非 ...

  2. UNIX网络编程学习指南--epoll函数

    epoll是select/poll的强化版,都是多路复用的函数,epoll有了很大的改进. epoll的功能 1.支持监听大数目的socket描述符 一个进程内,select能打开的fd是有限制的,有 ...

  3. UNIX网络编程——epoll 的accept , read, write(重要)

    在一个非阻塞的socket上调用read/write函数,返回EAGAIN或者EWOULDBLOCK(注:EAGAIN就是EWOULDBLOCK). 从字面上看,意思是: EAGAIN: 再试一次 E ...

  4. 《Unix 网络编程》14:高级 I/O 函数

    高级 I/O 函数 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ...

  5. 《 UNIX网络编程》源码的使用

    学习编程这东西,看代码,改代码,运行代码这样才能学到实际东西!本书说在www.unpbook.com可以获取源码,不过打不开!所以google unpv13e.tar.gz 并在网络上找到了:源码:h ...

  6. 记录一次配置unix网络编程环境的过程和遇到的问题

    记录一次搭建unix网络编程环境过程中遇到的问题和总结 计算机环境虚拟机 linuxmint-18-xfce-64bit 1.打开unix网络编程.iso 把目录下的文件复制到某一目录,修改权限,可命 ...

  7. 【unix网络编程第三版】阅读笔记(五):I/O复用:select和poll函数

    本博文主要针对UNP一书中的第六章内容来聊聊I/O复用技术以及其在网络编程中的实现 1. I/O复用技术 I/O多路复用是指内核一旦发现进程指定的一个或者多个I/O条件准备就绪,它就通知该进程.I/O ...

  8. UNIX网络编程——并发服务器(TCP)

    在迭代服务器中,服务器只能处理一个客户端的请求,如何同时服务多个客户端呢?在未讲到select/poll/epoll等高级IO之前,比较老土的办法是使用fork来实现. 网络服务器通常用fork来同时 ...

  9. 《Unix 网络编程》05:TCP C/S 程序示例

    TCP客户/服务器程序示例 系列文章导航:<Unix 网络编程>笔记 目标 ECHO-Application 结构如下: graph LR; A[标准输入/输出] --fgets--> ...

随机推荐

  1. 2017中国大学生程序设计竞赛 - 女生专场 Deleting Edges(思维+最短路)

    Deleting Edges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  2. 24 mysql怎么保证主备一致

    Mysql主备的基本原理 在状态1中,客户端直接访问节点A,而节点B只是备库,只是将A的binlog全部同步过来并应用到本地,这样可以保持节点B和节点A的数据是相同的. 当需要切换的时候,就变成状态2 ...

  3. 环境搭建:Vue环境搭建和项目初始化(ubuntu)

    1.    安装node.js(版本6.10.3) 首先确保系统安装来gcc,g++,如果没有则安装: $ sudo apt-get update $ sudo apt-get install gcc ...

  4. spark集群配置以及java操作spark小demo

    spark 安装 配置 使用java来操作spark spark 安装 tar -zxvf spark-2.4.0-bin-hadoop2.7.tgz rm spark-2.4.0-bin-hadoo ...

  5. 提高ListView的效率

    按照普通的写法,如果ListView里面有比较多的东西的话,在加载每一个Item的时候,是非常非常卡的.具体表现就是滚动起来的时候会看见明显的卡顿. 关键还是处理自定义Adapter里面的getVie ...

  6. delphi c++builder 判断工程类型 超级系统变量

    d:\program files (x86)\embarcadero\studio\16.0\SOURCE\RTL\SYS\SysInit.pas ModuleIsLib: Boolean;      ...

  7. iPython notebook 安装使用

    pip install jupyter jupyter notebook --allow-root

  8. linux tcpdump

    简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具. tcpdump可以将网络中传送的数据包的 ...

  9. 类型或命名空间名称“Interop”在类或命名空间“Microsoft.Office”中不存在(是否缺少程序集引用?)

    准备用C#编写Web程序,生成Excel报表,在使用下面语句时报错. using Microsoft.Office.Interop.Excel; 报错信息:类型或命名空间名称“Interop”在类或命 ...

  10. 面试题:四种Java线程池用法解析 !=!=未看

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? 1 2 3 4 5 6 7 8 new Thread(new Runnable() {     @Override ...