unix网络编程str_cli使用epoll实现

简介: unix网络编程str_cli使用epoll实现unix环境高级编程中也有这个函数,都是为了讲解IO多路转接。从本质上来看epoll就是一个改善了的select和poll,本质没发生任何变化,对于构建在poll,select和epoll上的框架使用者来说,没什么区别。

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);
}
目录
相关文章
|
6月前
|
API
网络编程与select/poll/epoll服务器的实现(1)
什么是网络编程?     本部分主要是介绍socket网络编程的基本API——并展示一个服务器与客户端连接的具体流程是如何的实现一个一对一的网络服务器程序
70 0
|
6月前
|
网络协议 Linux C++
Linux C/C++ 开发(学习笔记十二 ):TCP服务器(并发网络编程io多路复用epoll)
Linux C/C++ 开发(学习笔记十二 ):TCP服务器(并发网络编程io多路复用epoll)
116 0
|
6月前
|
网络协议 Linux Python
Python网络编程基础(Socket编程)epoll在Linux下的使用
【4月更文挑战第12天】在上一节中,我们介绍了使用`select`模块来实现非阻塞IO的方法。然而,`select`模块在处理大量并发连接时可能会存在性能问题。在Linux系统中,`epoll`机制提供了更高效的IO多路复用方式,能够更好地处理大量并发连接。
|
1月前
|
算法 Unix 数据安全/隐私保护
Python编程--UNIX口令破解机
Python编程--UNIX口令破解机
|
4月前
|
安全 Java Linux
(七)Java网络编程-IO模型篇之从BIO、NIO、AIO到内核select、epoll剖析!
IO(Input/Output)方面的基本知识,相信大家都不陌生,毕竟这也是在学习编程基础时就已经接触过的内容,但最初的IO教学大多数是停留在最基本的BIO,而并未对于NIO、AIO、多路复用等的高级内容进行详细讲述,但这些却是大部分高性能技术的底层核心,因此本文则准备围绕着IO知识进行展开。
165 1
|
4月前
|
存储 Java Unix
(八)Java网络编程之IO模型篇-内核Select、Poll、Epoll多路复用函数源码深度历险!
select/poll、epoll这些词汇相信诸位都不陌生,因为在Redis/Nginx/Netty等一些高性能技术栈的底层原理中,大家应该都见过它们的身影,接下来重点讲解这块内容。
|
5月前
|
Unix
Unix环境高级编程(第三版)中apue.h头文件及其依赖安装教程
Unix环境高级编程(第三版)中apue.h头文件及其依赖安装教程
109 0
|
6月前
|
NoSQL Java Linux
【Linux IO多路复用 】 Linux 网络编程 认知负荷与Epoll:高性能I-O多路复用的实现与优化
【Linux IO多路复用 】 Linux 网络编程 认知负荷与Epoll:高性能I-O多路复用的实现与优化
186 0
|
6月前
|
网络协议 Unix Linux
在Unix/Linux shell中,与网络相关的命令
在Unix/Linux shell中,与网络相关的命令
68 2
|
6月前
|
网络协议 Linux
2.1.1网络io与io多路复用select/poll/epoll
2.1.1网络io与io多路复用select/poll/epoll