#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/types.h> #include <errno.h> #include <sys/select.h>
#define BUF_LEN 1024 #define SERV_PORT 5358 #define FD_SIZE 513
ssize_t writen(int fd, const void *vptr, size_t n) { size_t nleft; ssize_t nwriten; const char *ptr;
ptr = vptr; nleft = n; while(nleft>0) { if((nwriten = write(fd, ptr, nleft)) <= 0) { if(nwriten < 0 && errno == EINTR) { nwriten = 0; /*interrupt by signal*/ } else { return -1; } }
nleft -= nwriten; ptr += nwriten; } return n; }
int main(int argc, char **argv) { int listenfd, connfd, sockfd, maxfd, maxi, i; int nready, client[FD_SIZE]; ssize_t n; fd_set rset, allset; char buf[BUF_LEN] = {0}; socklen_t clilen; struct sockaddr_in servaddr, cliaddr;
if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("socket error: %s\n", strerror(errno)); return 0; } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT);
if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { printf("bind error: %s\n", strerror(errno)); return 0; }
if(listen(listenfd, 256)) { printf("listen error: %s\n", strerror(errno)); } maxfd = listenfd; maxi = -1; for(i=0;i<FD_SIZE;i++) { client[i] = -1; } FD_ZERO(&allset); FD_SET(listenfd, &allset); while(1) { rset = allset; nready = select(maxfd+1, &rset, NULL, NULL, NULL);
if(FD_ISSET(listenfd, &rset)) { clilen = sizeof(cliaddr); if((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen)) == -1) { printf("accept error: %s\n", strerror(errno)); }
for(i=0;i<FD_SIZE;i++) { if(client[i] < 0) { client[i] = connfd; break; } } if(i == FD_SIZE) { printf("too many fd!\n"); exit(0); }
FD_SET(connfd, &allset); if (connfd > maxfd) maxfd = connfd; if (i > maxi) maxi = i; if (--nready <= 0) continue; } for(i=0;i<=maxi;i++) { if((sockfd = client[i]) < 0) continue; if(FD_ISSET(sockfd, &rset)) { if((n = read(sockfd, buf, BUF_LEN)) ==0) { close(sockfd); FD_CLR(sockfd, &allset); client[i] = -1; }else { fputs(buf, stdout); writen(sockfd, buf, n); bzero(buf, BUF_LEN); }
if(--nready <= 0) break; } } } return 0; }
|