#include #include #include #include #include #include #include #include /* port we're listening on */ #define PORT 2020 int main(int argc, char *argv[]) { argc = argc; /* master file descriptor list */ fd_set master; /* temp file descriptor list for select() */ fd_set read_fds; /* server address */ struct sockaddr_in serveraddr; /* client address */ struct sockaddr_in clientaddr; /* maximum file descriptor number */ int fdmax; /* listening socket descriptor */ int listener; /* newly accept()ed socket descriptor */ int newfd; /* buffer for client data */ char buf[1024]; int nbytes; /* for setsockopt() SO_REUSEADDR, below */ int yes = 1; socklen_t addrlen = 0; int i, j; /* clear the master and temp sets */ FD_ZERO(&master); FD_ZERO(&read_fds); /* get the listener */ if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Server-socket()"); exit(1); } printf("Server-socket() is OK...\n"); /*"address already in use" error message */ if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("Server-setsockopt()"); exit(1); } printf("Server-setsockopt() is OK...\n"); /* bind */ serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = INADDR_ANY; serveraddr.sin_port = htons(PORT); memset(&(serveraddr.sin_zero), '\0', 8); if(bind(listener, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1) { perror("Server-bind()"); exit(1); } printf("Server-bind() is OK...\n"); /* listen */ if(listen(listener, 10) == -1) { perror("Server-listen()"); exit(1); } printf("Server-listen() is OK...\n"); /* add the listener to the master set */ FD_SET(listener, &master); /* keep track of the biggest file descriptor */ fdmax = listener; /* so far, it's this one*/ /* loop */ for(;;) { /* copy it */ read_fds = master; if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { perror("Server-select()"); exit(1); } printf("Server-select() is OK...\n"); /*run through the existing connections looking for data to be read*/ for(i = 0; i <= fdmax; i++) { if(FD_ISSET(i, &read_fds)) { /* we got one... */ if(i == listener) { /* handle new connections */ addrlen = sizeof(clientaddr); if((newfd = accept(listener, (struct sockaddr *)&clientaddr, &addrlen)) == -1) { perror("Server-accept()"); } else { printf("Server-accept() is OK...\n"); FD_SET(newfd, &master); /* add to master set */ if(newfd > fdmax) { /* keep track of the maximum */ fdmax = newfd; } printf("%s: New connection from %s on socket %d\n" , argv[0], inet_ntoa(clientaddr.sin_addr), newfd); } } else { /* handle data from a client */ if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) { /* got error or connection closed by client */ if(nbytes == 0) /* connection closed */ printf("%s: socket %d hung up\n", argv[0], i); else perror("recv()"); /* close it... */ close(i); /* remove from master set */ FD_CLR(i, &master); } else { /* we got some data from a client*/ for(j = 0; j <= fdmax; j++) { /* send to everyone! */ if(FD_ISSET(j, &master)) { /* except the listener and ourselves */ if(j != listener && j != i) { if(send(j, buf, nbytes, 0) == -1) perror("send()"); } } } } } } } } return 0; }