• 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 
  • 相关阅读:
    【微信小程序】 自定义组件
    vue3中的组件通讯
    vue3如何使用watch监听
    windows server 2008中iis7中的php5.3出现 Server 内部错误500的解决
    在计算里面计算为什么要采用补码
    计算机里二进制与十进制互相转到到底是怎么完成的
    矩的概念、意义以及在SLAM中的应用
    VC++6.0 使用jsoncpp静态库解析json数据(亲测绝对可用)
    python等待用户输入并超时退出
    使用WTV工具箱检测有效电视源
  • 原文地址:https://www.cnblogs.com/zhangxuechao/p/11709442.html
Copyright © 2020-2023  润新知