#include "unp.h" #include // for OPEN_MAX #ifndef OPEN_MAX #define OPEN_MAX _SC_OPEN_MAX #endif int main(int argc, char *argv[]) { int listenfd, confd, sockfd, maxi, i; int nready; ssize_t n; char buf[MAXLINE]; 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(SERV_PORT); Bind(listenfd, (SA *)&servaddr, sizeof(servaddr)); Listen(listenfd, LISTENQ); client[0].fd = listenfd; client[0].events = POLLIN; for(i = 1; i < OPEN_MAX; i++) client[i].fd = -1; maxi = 0; for(;;) { nready = Poll(client, maxi + 1, INFTIM); if(client[0].revents & POLLIN) { // new client connection clilen = sizeof(cliaddr); confd = Accept(listenfd, (SA *) &cliaddr, &clilen); for ( i = 0; i < OPEN_MAX; i++) if(client[i].fd < 0) { client[i].fd = confd; // save descriptor break; } if( i == OPEN_MAX) err_quit("too many clients"); client[i].events = POLLIN; if( i > maxi) maxi = i; // max index in client[] array if(--nready <= 0) continue; // no more readable descriptor } for(i = 0; i <= maxi; i++) { // check all clients for data if((sockfd = client[i].fd) < 0) continue; if(client[i].revents & (POLLIN | POLLERR)) { if( (n = Read(sockfd, buf, MAXLINE)) < 0) { if( errno == ECONNRESET) { // connection closed by client Close(sockfd); client[i].fd = -1; } else { err_sys("read error"); } } else 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 } } } }