#include #include #include #include #include #include #include #include #define BUF_SIZE 512 int main(int argc, char *argv[]) { fd_set all_fds; /* Master set where we keep all file descriptors */ fd_set read_fds; /* This is a temporary set we will use with select() */ int listen_fd; /* File descriptor for listening */ int client_fd; /* File descriptor for clients */ struct sockaddr_in addr; /* Struct that holds server address */ struct sockaddr_in cli_addr; /* Struct that holds client address */ socklen_t cli_addrlen = sizeof(cli_addr); ssize_t nbytes; int fd, i; char data[BUF_SIZE]; memset(data, '\0', BUF_SIZE); /* empty the file descriptor sets */ FD_ZERO(&all_fds); FD_ZERO(&read_fds); /* initialize the struct with the server address */ addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(12345); memset(addr.sin_zero, '\0', sizeof(addr.sin_zero)); /* Create the listening socket */ listen_fd = socket(PF_INET, SOCK_STREAM, 0); /* Assign server address to the socket */ bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)); /* Start listening for connections */ listen(listen_fd, 10); /* Add listen socket fd to the master set */ FD_SET(listen_fd, &all_fds); for(;;) { read_fds = all_fds; /* select blocks until one of our sockets has data to read */ select(FD_SETSIZE, &read_fds, NULL, NULL, NULL); for (fd = 0; fd < FD_SETSIZE; fd++) { /* is the file descriptor ready for reading? */ if (FD_ISSET(fd, &read_fds)) { /* if it is the listening fd then we got a new connection */ if (fd == listen_fd) { /* accept the connection */ client_fd = accept(listen_fd, (struct sockaddr *)&cli_addr, &cli_addrlen); /* add fd to the master fd set */ FD_SET(client_fd, &all_fds); } else { /* else someone is trying to send data */ nbytes = read(fd, data, BUF_SIZE-1); switch(nbytes) { case -1: /* an error occured */ perror("read"); exit(1); case 0: /* client disconnected */ fprintf(stderr, "server: socket %d closed connection\n", fd); /* remove fd from the master fd set */ FD_CLR(fd, &all_fds); break; default: data[nbytes - 1] = '\0'; fprintf(stderr, "socket %d: %s\n", client_fd, data); for (i = 0; i < FD_SETSIZE; i++) { /* send the message to everyone except from * the sender and the server */ if (FD_ISSET(i, &all_fds) && i != fd && i != listen_fd) write(i, data, nbytes); } } } } } } return 0; }