#include #include #include #include #include #include #include #include #include #include #define PORT 8888 #define BUFF_SIZE 8192 #define MAX_CLIENTS 125 typedef struct { struct sockaddr_in clients[MAX_CLIENTS + 1]; int client_fds[MAX_CLIENTS + 1]; } DATA; void *process_clients(void *p) { DATA *data = (DATA *)p; char buf[BUFF_SIZE]; while (1) { off_t ret = read(STDIN_FILENO, buf, sizeof(buf)); if (ret <= 0) continue; socklen_t len = sizeof(struct sockaddr_in); for (size_t i = 0; i < MAX_CLIENTS; i++) if (data->client_fds[i] != -1) if (sendto(data->client_fds[i], buf, ret, 0, (struct sockaddr *)&data->clients[i], len) <= 0) data->client_fds[i] = -1; } } int main(void) { signal(SIGPIPE, SIG_IGN); int fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) goto ERROR_WITHOUTCLOSE; struct timeval tv = {.tv_sec = 0, .tv_usec = 0}; if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0) goto ERROR; int reuse = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(int)) < 0) goto ERROR; static struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) goto ERROR; if (listen(fd, 0) < 0) goto ERROR; /* Thread of common buffer */ static DATA data; memset(data.client_fds, -1, sizeof(data.client_fds)); pthread_t td; pthread_create(&td, NULL, process_clients, (void *)&data); /* Accept clients and update the fds buffer */ socklen_t len = sizeof(addr); while (1) { int client_fd = accept(fd, (struct sockaddr *)&addr, &len); if (client_fd < 0) continue; for (size_t i = 0; i < MAX_CLIENTS; i++) { if (data.client_fds[i] == -1) { data.clients[i] = addr; data.client_fds[i] = client_fd; break; } } } ERROR: close(fd); ERROR_WITHOUTCLOSE: fprintf(stderr, "streamer: %s\n", strerror(errno)); return 1; }