栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux c epoll使用

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux c epoll使用

文章目录
  • 1、函数介绍
  • 2、使用
  • 3、socket常用函数出错处理封装

1、函数介绍

1.1、创建一颗树,返回值指向树的根节点

#include 

int epoll_create(int size);
参数:
    size 创建的红黑树的监听数据节点(数目最大有多大,从Linux 2.6.8开始,max_size参数将被忽略,但必须大于零。)
返回值:
    成功 指向新创建的红黑树的根节点fd
    失败 -1 errno

1.2、对树进行操作(增加,修改,删除)节点

int epoll_ctl(int epfd,int op,int fd,struct epoll_event* event);
参数:
    epfd: epoll_create 函数的返回值
    op: 对该监听的红黑树操作
        EPOLL_CTL_ADD   添加fd到 监听红黑树
        EPOLL_CTL_MOD   修改fd在监听红黑树上的监听事件
        EPOLL_CTL_DEL   将一个fd从监听红黑树上摘下(取消监听)
        
    fd:待监听的fd
    
    event:结构体的地址
        struct epoll_event {
            uint32_t     events;      
            // EPOLLIN / EPOLLOUT / EPOLLERR
            
            epoll_data_t data;    
            // fd 对应监听事件的fd
            // void* ptr
            // u32
            // u64
        };
        typedef union epoll_data {
                void        *ptr;
                int          fd;
                uint32_t     u32;
                uint64_t     u64;
        } epoll_data_t;


返回值:
    成功 0
    失败 -1 errno

1.3、阻塞监听树上面节点的请求,将请求返回到数组中

int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout);
参数:
    epfd:epoll_create 函数返回值 epfd
    events:传出参数【数组】,满足监听条件的
    maxevents:数组 元素的总个数1024
    timeout:毫秒
        -1 阻塞
        0 不阻塞
        >0  超时事件(毫秒)
返回值:
    >0 满足监听的总个数,可以用作循环上限
    0 没有fd满足条件
    -1 errno
2、使用
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "socket_wrap.h"

#define OPEN_MAX 1024

int main()
{
    int i,listenfd,connfd,sockfd,j;
    int n,num = 0;
    ssize_t nready,efd,res;
    char buf[1024],str[INET_ADDRSTRLEN];
    socklen_t clilen;
    struct sockaddr_in cliaddr,servaddr;
    struct epoll_event tep,ep[OPEN_MAX];   
    listenfd = Socket(AF_INET,SOCK_STREAM,0);
    int opt = 0;
    setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(9999);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    Bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
    Listen(listenfd,128);

    efd = epoll_create(OPEN_MAX);
    if(efd == -1)
        perr_exit("epoll _create error");

    tep.events = EPOLLIN;
    tep.data.fd = listenfd;

    res = epoll_ctl(efd,EPOLL_CTL_ADD,listenfd,&tep);
    if(res == -1)
        perr_exit("epoll_ctl error");
    while (1)
    {
        nready = epoll_wait(efd,ep,OPEN_MAX,-1);
        if(nready == -1)
            perr_exit("epoll_wait error");
        for(i=0;i 
3、socket常用函数出错处理封装 

socket_wrap.h

#ifndef __WRAP_H_
#define __WRAP_H_

void perr_exit(const char* s);
int Accept(int fd,struct sockaddr* sa,socklen_t* salenptr);
int Bind(int fd,const struct sockaddr* sa,socklen_t salen);
int Connect(int fd,const struct sockaddr* sa,socklen_t salen);
int Listen(int fd,int backlog);
int Socket(int family,int type,int protocol);
ssize_t Read(int fd,void* ptr,size_t nbytes);
ssize_t Write(int fd,const void* ptr,size_t nbytes);
int Close(int fd);
ssize_t Readn(int fd,void* vptr,size_t n);
ssize_t Writen(int fd,const void* vptr,size_t n);
static ssize_t my_read(int fd,char* ptr);
ssize_t Readline(int fd,void* vptr,size_t maxlen);

#endif // !__WRAP_H_

socket_wrap.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "socket_wrap.h"

void perr_exit(const char* s)
{
    perror(s);
    exit(1);
}

int Accept(int fd,struct sockaddr* sa,socklen_t* salenptr)
{
    int n;
again:
    if((n=accept(fd,sa,salenptr))<0)
    {
        if(errno == EConNABORTED || (errno==EINTR))
            goto again;
        else
            perr_exit("accept error");
    }
    return n;
}

int Bind(int fd,const struct sockaddr* sa,socklen_t salen)
{
    int n;
    if((n=bind(fd,sa,salen))<0)
    {
        perr_exit("bind error");
    }
    return n;
}

int Connect(int fd,const struct sockaddr* sa,socklen_t salen)
{
    int n;
    if((n=connect(fd,sa,salen))<0)
        perr_exit("connect error");
    return n;

}

int Listen(int fd,int backlog)
{
    int n;
    if((n=listen(fd,n))<0)
    {
        perr_exit("listen error");
    }
    return n;
}


int Socket(int family,int type,int protocol)
{
    int n;
    if((n=socket(family,type,protocol))<0)
        perr_exit("socket error");
    return n;
}

ssize_t Read(int fd,void* ptr,size_t nbytes)
{
    ssize_t n;
again:
    if((n=read(fd,ptr,nbytes))<0)
    {
        if(errno==EINTR)
            goto again;
        else
            return -1;
    }
    return n;
}

ssize_t Write(int fd,const void* ptr,size_t nbytes)
{
    ssize_t n;
    if((n=write(fd,ptr,nbytes))<0)
        perr_exit("write error");
    return n;
}

int Close(int fd)
{
    int n;
    if((n=close(fd))<0)
        perr_exit("close error");
    return n;
}

ssize_t Readn(int fd,void* vptr,size_t n)
{
    size_t nleft;   // unsigned int 剩余未读取字节数
    ssize_t nread; // int 实际读到的字节数
    char* ptr;
    ptr = vptr;
    nleft = n;
    while (nleft>0)
    {
        if((nread = read(fd,ptr,nleft))<0)
        {
            if(errno == EINTR)        
                nread = 0;
            else
             return -1;
        }
        else if(nread == 0)
            break;
        nleft -= nread;
        ptr+=nread;
    }
    return n-nread;
    
}

ssize_t Writen(int fd,const void* vptr,size_t n)
{
    size_t nleft;
    ssize_t nwritten;
    const char* ptr;
    ptr = vptr;
    nleft = n;
    while(nleft>0)
    {
        if((nwritten=write(fd,ptr,nleft))<=0)
        {
            if(nwritten<0 && errno==EINTR)
                nwritten = 0;
            else
                return -1;
        }
        nleft -= nwritten;
        ptr += nwritten;
    }
    return n;
}

static ssize_t my_read(int fd,char* ptr)
{
    static int read_cnt;
    static char* read_ptr;
    static char read_buf[100];
    if(read_cnt<=0)
    {
    again:
        if((read_cnt=read(fd,read_buf,sizeof(read_buf)))<0)
        {
            if(errno == EINTR)
                goto again;
            return -1;
        }
        else if(read_cnt == 0)
            return 0;
        read_ptr = read_buf;
    }
    read_cnt--;
    *ptr = *read_ptr++;
    return 1;
}

// 传出参数 vptr
ssize_t Readline(int fd,void* vptr,size_t maxlen)
{
    ssize_t n,rc;
    char c,*ptr;
    ptr = vptr;
    for(n=1;n
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/461307.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号