#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/select.h>

#define PORT 8000
#define MAX_CLIENTS 30

int main() {
    int server_fd, client_fd, max_fd, optval = 1;
    struct sockaddr_in address;
    int clients[MAX_CLIENTS] = {0};
    char buffer[1024] = {0};
    int active_clients = 0;
    fd_set read_fds;
    int i;

    // создаем серверный сокет
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror(“Socket failed”);
        exit(EXIT_FAILURE);
    }

    // настройка опций сокета
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) {
        perror(“Setsockopt failed”);
        exit(EXIT_FAILURE);
    }

    // настройка адреса сервера
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    // связывание серверного сокета с адресом
    if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
        perror(“Bind failed”);
        exit(EXIT_FAILURE);
    }

    // установка серверного сокета в режим прослушивания
    if (listen(server_fd, 5) < 0) {
        perror(“Listen failed”);
        exit(EXIT_FAILURE);
    }

    // добавляем серверный сокет в множество файловых дескрипторов для чтения
    FD_ZERO(&read_fds);
    FD_SET(server_fd, &read_fds);
    max_fd = server_fd;

    while (1) {
        // ожидаем событий на сокетах
        if (select(max_fd + 1, &read_fds, NULL, NULL, NULL) < 0) {
            perror(“Select failed”);
            exit(EXIT_FAILURE);
        }

        // обрабатываем события на сокетах
        for (i = 0; i <= max_fd; i++) {
            if (!FD_ISSET(i, &read_fds)) {
                continue;
            }

            if (i == server_fd) { // новое подключение
                if ((client_fd = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&address)) < 0) {
                    perror(“Accept failed”);
                    exit(EXIT_FAILURE);
                }

                printf(“New connection: %s:%d\n”, inet_ntoa(address.sin_addr), ntohs(address.sin_port));

                if (active_clients >= MAX_CLIENTS) {
                    printf(“Connection refused: max clients reached\n”);
                    close(client_fd);
                    continue;
                }

                // добавляем новый клиентский сокет в множество файловых дескрипторов для чтения
                FD_SET(client_fd, &read_fds);
                if (client_fd > max_fd) {
                    max_fd = client_fd;
                }
                clients[active_clients] = client_fd;
                active_clients++;
            } else { // данные от клиента
                if (recv(i, buffer, 1024, 0) == 0) {
                    // клиент отключился
                    getpeername(i, (struct sockaddr*)&address, (socklen_t*)&address);
                    printf(“Disconnected: %s:%d\n”, inet_ntoa(address.sin_addr), ntohs(address.sin_port));
                    close(i);
                    FD_CLR(i, &read_fds);
                    for (int j = 0; j < active_clients; j++) {
                        if (clients[j] == i) {
                            clients[j] = 0;
                            break;
                        }
                    }
                    active_clients–;
                } else {
                    // обработка полученных данных от клиента
                    printf(“Received data from %d: %s\n”, i, buffer);
                    // …
                }
            }
        }
    }

    return 0;
}
Ошибка сегментирования (стек памяти сброшен на диск)