#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> int main(int ac, char **av) { int i, port; int sfd, cfd, clen; struct sockaddr_in saddr, caddr; fd_set rfs; for(i=1; i<ac; i++) if(strcmp(av[i], "-p") == 0) break; if(i+1 >= ac){ fprintf(stderr, "-p port\n"); exit(1); } port = strtol(av[i+1], NULL, 0); if((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ perror("socket"); exit(1); } memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(port); if(bind(sfd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1){ perror("bind"); exit(1); } if(listen(sfd, 5) == -1){ perror("listen"); exit(1); } FD_ZERO(&rfs); FD_SET(0, &rfs); FD_SET(sfd, &rfs); while(1){ int nfds = 0, fd, fd2; fd_set res_rfs = rfs; for(fd=0; fd<FD_SETSIZE; fd++) if(FD_ISSET(fd, &res_rfs) && fd > nfds) nfds = fd; if(select(nfds+1, &res_rfs, NULL, NULL, NULL) <= 0) continue; for(fd=0; fd<FD_SETSIZE; fd++){ char buf[4096]; int n; if(!FD_ISSET(fd, &res_rfs)) continue; if(fd == 0){ n = read(0, buf, sizeof(buf)); for(fd2=4; fd2<FD_SETSIZE; fd2++){ if(!FD_ISSET(fd2, &rfs)) continue; write(fd2, buf, n); } }else if(fd == sfd){ memset(&caddr, 0, sizeof(caddr)); clen = sizeof(caddr); if((cfd = accept(sfd, (struct sockaddr *)&caddr, (socklen_t *)&clen)) == -1){ perror("accept"); exit(1); } FD_SET(cfd, &rfs); }else{ n = read(fd, buf, sizeof(buf)); if(n > 0) write(1, buf, n); else FD_CLR(fd, &rfs); } } } return 0; } /* EOF */