#include #include #include #include #include #include #include #include typedef struct s_client { int id; char msg[1024]; } t_client; t_client clients[1024]; fd_set readfds, writefds, active; int fd_max; int id_next; char bufread[120000]; char bufwrite[120000]; void error(char *msg) { write(2, msg, strlen(msg)); exit(1); } void broadcast(int not) { for(int fd = 0; fd <= fd_max; ++fd) { if (fd == not) continue; if (FD_ISSET(fd, &writefds)) send(fd, bufwrite, strlen(bufwrite), 0); } } int main(int ac, char **av) { int sockfd, connfd, res; struct sockaddr_in servaddr, cli; socklen_t len; if (ac != 2) error("Wrong number of arguments\n"); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) error("Fatal error\n"); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(2130706433); servaddr.sin_port = htons(atoi(av[1])); if ((bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr))) == -1) error("Fatal error\n"); if (listen(sockfd, 10) == -1) error("Fatal error\n"); len = sizeof(cli); FD_ZERO(&active); FD_SET(sockfd, &active); bzero(&clients, sizeof(clients)); fd_max = sockfd; while(1) { readfds = active; writefds = active; if (select(fd_max + 1, &readfds, &writefds, NULL, NULL) < 0) continue; for(int fd_i = 0; fd_i <= fd_max; ++fd_i) { if (FD_ISSET(fd_i, &readfds) && fd_i == sockfd) { connfd = accept(sockfd, (struct sockaddr *)&cli, &len); if (connfd < 0) continue; if (connfd > fd_max) fd_max = connfd; clients[connfd].id = id_next++; FD_SET(connfd, &active); sprintf(bufwrite, "server: client %d just arrived\n", clients[connfd].id); broadcast(connfd); break; } if (FD_ISSET(fd_i, &readfds) && fd_i != sockfd) { res = recv(fd_i, bufread, 65536, 0); if (res <= 0) { sprintf(bufwrite, "server: client %d just left\n", clients[fd_i].id); broadcast(fd_i); FD_CLR(fd_i, &active); close(fd_i); break; } else { for(int i = 0, j = strlen(clients[fd_i].msg); i < res; ++i, ++j) { clients[fd_i].msg[j] = bufread[i]; if (clients[fd_i].msg[j] == '\n') { clients[fd_i].msg[j] = '\0'; sprintf(bufwrite, "client %d: %s\n", clients[fd_i].id, clients[fd_i].msg); broadcast(fd_i); bzero(clients[fd_i].msg, strlen(clients[fd_i].msg)); j = -1; } } break; } } } } }