0Pricing
C Academy · Lektion

Mehrere Clients verarbeiten

select und poll

Mehrere Clients verarbeiten ist eine kostenlose C Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C Academy-Kurs umfasst insgesamt 4 Lektionen.

Das Nebenläufigkeitsproblem

Ein einfacher Server verarbeitet jeweils einen Client. Wenn ein Client langsam ist, müssen alle anderen warten. Um viele Clients gleichzeitig zu bedienen, benötigen Sie ein anderes Modell.

Ansätze für Nebenläufigkeit

Drei gängige Strategien:

  • Ein Thread/Prozess pro Client: einfach, aber bei hoher Skalierung ressourcenintensiv
  • I/O-Multiplexing mit select oder poll: Ein Thread überwacht viele Sockets
  • Ereignisschleifen mit epoll/kqueue: skalierbar auf Tausende

Was select macht

select() überwacht eine Gruppe von Dateideskriptoren und teilt Ihnen in einem einzigen blockierenden Aufruf mit, welche zum Lesen oder Schreiben bereit sind oder Fehler aufweisen. Dadurch kann ein Thread viele Sockets bedienen.

Grundlagen von fd_set

select verwendet eine Bitmaske vom Typ fd_set. Verwalten Sie sie mit den Makros FD_ZERO, FD_SET, FD_CLR und FD_ISSET.

#include <sys/select.h>

void setup_set(fd_set *set, int listen_fd) {
    FD_ZERO(set);          /* clear all */
    FD_SET(listen_fd, set); /* watch the listener */
}

select aufrufen

select benötigt den höchsten fd plus eins und verändert die Menge direkt, um bereite Deskriptoren zu markieren. Da der Aufruf destruktiv ist, müssen Sie die Menge vor jedem Aufruf neu aufbauen.

#include <sys/select.h>
#include <stdio.h>

int wait_ready(int maxfd, fd_set *read_set) {
    int n = select(maxfd + 1, read_set, NULL, NULL, NULL);
    if (n < 0) perror("select");
    return n; /* number of ready fds */
}

Die select-Serverschleife

Das Muster: Bauen Sie die Menge neu auf, rufen Sie select auf und verarbeiten Sie dann jeden bereiten fd: Entweder akzeptieren Sie einen neuen Client (wenn es der Listener ist) oder lesen Daten (wenn es ein Client ist).

#include <sys/select.h>

void loop_skeleton(int listen_fd, fd_set *master, int maxfd) {
    fd_set work;
    for (;;) {
        work = *master;           /* copy, select destroys it */
        select(maxfd + 1, &work, NULL, NULL, NULL);
        for (int fd = 0; fd <= maxfd; fd++) {
            if (!FD_ISSET(fd, &work)) continue;
            /* fd == listen_fd -> accept; else -> recv */
        }
    }
}

Clients verwalten

Wenn Sie eine neue Verbindung akzeptieren, fügen Sie deren fd zur Hauptmenge hinzu und aktualisieren Sie maxfd. Wenn ein Client die Verbindung trennt (recv gibt 0 zurück), rufen Sie close auf und entfernen Sie den fd mit FD_CLR aus der Menge.

#include <sys/select.h>
#include <unistd.h>

void add_client(fd_set *master, int *maxfd, int conn) {
    FD_SET(conn, master);
    if (conn > *maxfd) *maxfd = conn;
}
void drop_client(fd_set *master, int conn) {
    close(conn);
    FD_CLR(conn, master);
}

Grenzen von select

select hat einige Nachteile:

  • Begrenzt auf FD_SETUP Deskriptoren (oft 1024)
  • O(n)-Durchlauf aller fds bei jedem Aufruf
  • Die Menge muss bei jeder Iteration neu aufgebaut werden

Für viele Verbindungen skalieren poll oder epoll besser.

Was poll bietet

poll() verwendet ein Array aus struct pollfd statt einer festen Bitmaske. Daher gibt es keine Begrenzung auf 1024 Deskriptoren, und die Eingabe wird bei jedem Aufruf nicht zerstört.

#include <poll.h>

void setup_poll(struct pollfd *pfd, int listen_fd) {
    pfd[0].fd = listen_fd;
    pfd[0].events = POLLIN; /* notify when readable */
}

poll aufrufen

poll blockiert, bis mindestens ein fd bereit ist (oder das Zeitlimit abläuft), und setzt dann revents für jeden bereiten Eintrag.

#include <poll.h>
#include <stdio.h>

int poll_ready(struct pollfd *pfds, int count) {
    int n = poll(pfds, count, -1); /* -1 = block forever */
    if (n < 0) perror("poll");
    return n;
}

Hochskalieren mit epoll

Für Tausende von Verbindungen liefern Linux' epoll und BSDs kqueue nur die bereiten Deskriptoren mit O(1) pro Ereignis. Dadurch vermeiden sie den vollständigen Durchlauf, den select und poll durchführen.

Schnelltest

Testen Sie Ihr Verständnis der Verarbeitung mehrerer Clients.

Zusammenfassung

Sie haben gelernt, viele Clients mit einem Thread zu bedienen.

  • select überwacht viele fds; verwalten Sie sie mit FD_-Makros
  • Bauen Sie die Menge in jeder Schleife neu auf, da select destruktiv ist
  • Fügen Sie akzeptierte Clients zur Menge hinzu; entfernen Sie sie bei Verbindungsabbruch
  • poll vermeidet das Limit von 1024; epoll skaliert auf Tausende

Häufig gestellte Fragen

Ist die Lektion „Mehrere Clients verarbeiten“ kostenlos?

Ja — der vollständige Text von „Mehrere Clients verarbeiten“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Mehrere Clients verarbeiten“?

select und poll Du übst C Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um C Academy zu starten?

Keine Vorkenntnisse erforderlich. C Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Mehrere Clients verarbeiten“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser C Academy-Lektion Code schreiben und ausführen?

Ja. Jede C Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Überblick über Sockets
  2. TCP-Server
  3. TCP-Client
  4. Mehrere Clients verarbeiten
← Zurück zu C Academy