zoukankan      html  css  js  c++  java
  • 使用poll处理任意数目个客户的单进程程序

    http://www.cnblogs.com/nufangrensheng/p/3590002.html中的select改用poll。

    int
    main(int argc, char **argv)
    {
        int                     i, maxi, listenfd, connfd, sockfd;
        int                     nready;
        ssize_t                 n;
        char                    buf[4096];
        socklen_t               clilen;
        struct    pollfd        client[OPEN_MAX];
        struct sockaddr_in      cliaddr, servaddr;
    
        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(9877);
    
        bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
        
        listen(listenfd, 5);
        
        client[0].fd = listenfd;
        client[0].events = POLLRDNORM;
    
        for(i = 0; i < OPEN_MAX; i++)
            client[i].fd = -1;    /* -1 indicates available entry */
        maxi = 0;            /* max index into client[] array */
    
        for(;;)    
        {
            nready = poll(client, maxi+1; INFTIM);
            
            if(client[0].revents & POLLRDNORM)    /* new client connection */
            {
                clilen = sizeof(cliaddr);
                connfd = accept(listenfd, (struct sockadr *)&cliaddr, &clilen);
    
                for(i = 1; i < OPEN_MAX;i++)
                {
                    if(client[i].fd < 0)
                    {
                        client[i].fd = connfd;    /* save descriptor */
                        break;
                    }
                }
    
                if(i == OPEN_MAX)
                {
                    printf("too many clients
    ");
                    exit(1);    
                }
                client[i].events = POLLRDNORM;
                if(i > maxi)
                    maxi = i;
    
                if(--nready <= 0)
                    continue;    /* no more readable descriptors */
            }
    
            for(i = 1; i <= maxi; i++)    /*  check all clients for data */
            {
                if((sockfd = client[i].fd) < 0)
                    continue;
                if(client[i].revents & (POLLRDNORM | POLLERR))
                {
                    if((n = read(sockfd, buf, 4096)) < 0)
                    {
                        if(errno == ECONNRESET)
                        {
                            /* connection reset by client */
                            close(sockfd);
                            client[i].fd = -1;
                        }
                        else
                        {
                            perror("read");
                            exit(1);
                        }
                    }
                    esle if(n == 0)
                    {
                        /* connection closed by client */
                        close(sockfd);
                        client[i].fd = -1;
                    }
                    else
                    {
                        writen(sockfd, buf, n);
                    }
                    if(--nready <= 0)
                        break;        /* no more readable descriptors */
                }
            }
        }
    }
  • 相关阅读:
    gorilla/mux 的学习
    SwitchyOmega 配置
    golang []byte 和 string相互转换
    golang 并发demo 写入 redis
    VS2010 显示TFS删除项
    WPF之转换器
    DataTemplate的用法
    DynamicResource与StaticResource的区别
    除非Windows Activation Service (WAS)和万维网发布服务(W3SVC)均处于运行状态,否则无法启动网站。
    WPF 可视化树的用途
  • 原文地址:https://www.cnblogs.com/nufangrensheng/p/3590197.html
Copyright © 2011-2022 走看看