#include #include #include #include #include #include #include #include #include #include #define PORT 8889 #define BUFF_SIZE 8192 #define MAX_CLIENTS 125 typedef struct { int fd; struct sockaddr_in clients[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++) sendto(data->fd, buf, ret, 0, (struct sockaddr *)&data->clients[i], len); } } int main(void) { signal(SIGPIPE, SIG_IGN); int fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) goto ERROR_WITHOUTCLOSE; struct timeval tv = {.tv_sec = 0, .tv_usec = 50}; if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) goto ERROR; 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; static DATA data; data.fd = fd; pthread_t td; pthread_create(&td, NULL, process_clients, (void *)&data); int last = 0; char buf[1]; socklen_t len = sizeof(struct sockaddr_in); while (1) { if (last <= MAX_CLIENTS) { if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&data.clients[last], &len) > 0) last++; } else last = 0; } ERROR: close(fd); ERROR_WITHOUTCLOSE: fprintf(stderr, "streamer: %s\n", strerror(errno)); return 1; }