zoukankan      html  css  js  c++  java
  • epoll函数

    socket描述符
    在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max查看,一般来说这个数目和系统内存关系很大

    epoll_create

    int epoll_create(int size);

    创建一个epoll的句柄。size为epoll所支持的最大句柄数

    epoll_wait

    int epoll_wait(int epfd, struct epoll_event *events,
                          int maxevents, int timeout);

    events:储存所有的读写事件
    maxevents:最大事件数量

    epoll_ctl

    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *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用来添加/修改/删除需要侦听的文件描述符及其事件。任何被侦听的文件符只要被关闭,那么它也会自动从被侦听的文件描述符集合中删除;要尽量少地调用epoll_ctl,防止其引来的开销
    EPOLL_CTL_ADD:添加
    EPOLL_CTL_MOD:修改
    EPOLL_CTL_DEL:删除

    举例

    int epfd = epoll_create(10);
    if(epfd < 0)
    {
        perror("epoll_create");
        return epfd;
    }
    
    struct epoll_event ev = {0};
    struct epoll_event events[10] = {0};
    
    ev.data.fd = sockfd;
    ev.events = EPOLLIN|EPOLLET;
    
    int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
    if(ret < 0)
    {
        perror("epoll_ctl");
        return ret;
    }
    
    for(;;)
    {
        int epfds = epoll_wait(epfd, events, 10, 500);
        if(epfds < 0)
        {
            perror("epoll_wait");
            return epfds;
        }
    
        int i = 0;
        for(i = 0; i < epfds; i++)
        {
            if(events[i].data.fd == sockfd)
            {
                struct sockaddr_in ss;
                socklen_t len = sizeof ss;
                int afd = accept(sockfd, (struct sockaddr*)&ss, &len);
                if(afd < 0)
                {
                    perror("accept");
                    return afd;
                }
    
                printf("接受到新连接 %d
    ", afd);
    
                ev.data.fd = afd;
                ev.events = EPOLLIN|EPOLLET;
    
                int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, afd, &ev);
                if(ret < 0)
                {
                    perror("epoll_ctl");
                    return ret;
                }
            }
            else if(events[i].events & EPOLLIN)
            {
                char buf[100] = {0};
                memset(buf, 0, sizeof(buf));
                int r = recv(events[i].data.fd, buf, sizeof(buf), 0);
                if(r > 0)
                {
                    printf("接收到数据 [%d]: %s
    ", events[i].data.fd, buf);
                }
            }
        }
    }

    实验现象

    # ./a.out 
    接受到新连接 5
    接收到数据 [5]: hello 
  • 相关阅读:
    mysql数据库 --数据类型、约束条件
    并发编程 --线程
    并发编程 --进程
    MySQL数据库 --基础
    网络编程之 TCP-UDP的详细介绍
    网络编程之 OSI七层协议
    python 元类、单例模式
    python 面向对象_多态、内置方法、反射
    Python 面向对象_继承、组合
    简单工厂设计模式
  • 原文地址:https://www.cnblogs.com/zhangxuechao/p/11709442.html
Copyright © 2011-2022 走看看