• linux高性能服务器编程第九章 I/O复用 (2)


    poll

    poll  

    #include <poll.h>
    // fds 结构体类型数组 指定我们感兴趣的文件描述符上发生的可读可写和异常事件\
    // nfds 遍历结合大小 左闭右开
    // timeout 单位为毫秒 -1 为阻塞 0 为立即返回
    int poll(struct pollfd* fds, nfds_t nfds, int timeout);
    
    struct pollfd
    {
        int fd;
        short events;  //注册的事件, 告知poll监听fd上的哪些事件
        short revents; // 实际发生的事件
    }
    #define exit_if(r, ...) \
    {   \
        if (r)  \
        {   \
            printf(__VA_ARGS__);    \
            printf("errno no: %d, error msg is %s", errno, strerror(errno));    \
            exit(1);    \
        }   \
    }   \
    
    struct client_info
    {
        char *ip_;
        int port_;
    };
    
    int main(int argc, char* argv[])
    {
        int port = 8001;
        char ip[] = "127.0.0.1";
    
        struct sockaddr_in address;
        address.sin_port = htons(port);
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = htons(INADDR_ANY);
    
        int listenfd = socket(PF_INET, SOCK_STREAM, 0);
        exit_if(listenfd < 0, "socket error\n");
    
        int ret = bind(listenfd, (struct sockaddr*)&address, sizeof(address));
        exit_if(ret == -1, "bind error\n");
    
        ret = listen(listenfd, 5);
        exit_if(ret == -1, "listen error\n");
    
        constexpr int MAX_CLIENTS = 1024;
        struct pollfd polls[MAX_CLIENTS] = {};
        struct client_info clientsinfo[MAX_CLIENTS] = {};
    
        polls[3].fd = listenfd;
        polls[3].events = POLLIN | POLLRDHUP;
    
    
        while (true)
        {
            ret = poll(polls, MAX_CLIENTS + 1, -1);
            exit_if(ret == -1, "poll error\n");
    
            for (int i = 3; i <= MAX_CLIENTS; ++i)
            {
                int fd = polls[i].fd;
    
                if (polls[i].revents & POLLRDHUP)
                {
                    polls[i].events = 0;
                    printf("close fd-%d from %s:%d\n", fd, clientsinfo[fd].ip_, clientsinfo[fd].port_);
                }
    
                if (polls[i].revents & POLLIN)
                {
                    if (fd == listenfd)
                    {
                        struct sockaddr_in client_address;
                        socklen_t client_addresslen = sizeof(client_address);
    
                        int clientfd = accept(listenfd, (struct sockaddr*)&client_address,
                                &client_addresslen);
    
                        struct client_info *clientinfo = &clientsinfo[clientfd];
    
                        clientinfo->ip_ = inet_ntoa(client_address.sin_addr);
                        clientinfo->port_ = ntohs(client_address.sin_port);
    
                        exit_if(clientfd < 0, "accpet error, from %s:%d\n", clientinfo->ip_,
                                clientinfo->port_);
                        printf("accept from %s:%d\n", clientinfo->ip_, clientinfo->port_);
    
                        polls[clientfd].fd = clientfd;
                        polls[clientfd].events = POLLIN | POLLRDHUP;
                    }
                    else
                    {
                        char buffer[1024];
                        memset(buffer, '\0', sizeof(buffer));
    
                        ret = read(fd, buffer, 1024);
                        if(ret == 0)
                        {
                            close(fd);
                        }
                        else
                        {
                            printf("recv from %s:%d:\n%s\n", clientsinfo[fd].ip_,
                                   clientsinfo[fd].port_, buffer);
                        }
                    }
                }
            }
        }
    }
  • 相关阅读:
    Spring Cloud 学习推荐
    Spring-Boot-应用可视化监控
    How to Convert a Class File to a Java File?
    Nacos Cluster Building
    基于Opentracing+Jaeger全链路灰度调用链
    Opentracing + Uber Jaeger 全链路灰度调用链,Nepxion Discovery
    What happened when new an object in JVM ?
    Sentinel Getting Started And Integration of Spring Cloud Alibaba Tutorials
    APK重签名总结
    C++矩阵运算库推荐
  • 原文地址:https://www.cnblogs.com/mjhjl/p/16229184.html
Copyright © 2020-2023  润新知