Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
unpv13e/tcpcliserv/tcpservpoll01.c
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
91 lines (78 sloc)
2.23 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* include fig01 */ | |
#include "unp.h" | |
#include <limits.h> /* for OPEN_MAX */ | |
int | |
main(int argc, char **argv) | |
{ | |
int i, maxi, listenfd, connfd, sockfd; | |
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 = POLLRDNORM; | |
for (i = 1; i < OPEN_MAX; i++) | |
client[i].fd = -1; /* -1 indicates available entry */ | |
maxi = 0; /* max index into client[] array */ | |
/* end fig01 */ | |
/* include fig02 */ | |
for ( ; ; ) { | |
nready = Poll(client, maxi+1, INFTIM); | |
if (client[0].revents & POLLRDNORM) { /* new client connection */ | |
clilen = sizeof(cliaddr); | |
connfd = Accept(listenfd, (SA *) &cliaddr, &clilen); | |
#ifdef NOTDEF | |
printf("new client: %s\n", Sock_ntop((SA *) &cliaddr, clilen)); | |
#endif | |
for (i = 1; i < OPEN_MAX; i++) | |
if (client[i].fd < 0) { | |
client[i].fd = connfd; /* save descriptor */ | |
break; | |
} | |
if (i == OPEN_MAX) | |
err_quit("too many clients"); | |
client[i].events = POLLRDNORM; | |
if (i > maxi) | |
maxi = i; /* max index in client[] array */ | |
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, MAXLINE)) < 0) { | |
if (errno == ECONNRESET) { | |
/*4connection reset by client */ | |
#ifdef NOTDEF | |
printf("client[%d] aborted connection\n", i); | |
#endif | |
Close(sockfd); | |
client[i].fd = -1; | |
} else | |
err_sys("read error"); | |
} else if (n == 0) { | |
/*4connection closed by client */ | |
#ifdef NOTDEF | |
printf("client[%d] closed connection\n", i); | |
#endif | |
Close(sockfd); | |
client[i].fd = -1; | |
} else | |
Writen(sockfd, buf, n); | |
if (--nready <= 0) | |
break; /* no more readable descriptors */ | |
} | |
} | |
} | |
} | |
/* end fig02 */ |