使用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 */
            }
        }
    }
}
原文地址:https://www.cnblogs.com/nufangrensheng/p/3590197.html