Aktueller Standort: Startseite> Neueste Artikel> Wie verwendete ich Socket_accept, um die Verarbeitung von Multi-Thread- oder Multi-Process-Verbindungen zu implementieren? (Kombiniert mit PCNTL_FORK Praktische Erklärung)

Wie verwendete ich Socket_accept, um die Verarbeitung von Multi-Thread- oder Multi-Process-Verbindungen zu implementieren? (Kombiniert mit PCNTL_FORK Praktische Erklärung)

M66 2025-06-11

In PHP ist Socket_accecece eine Schlüsselfunktion, die Client -Verbindungen bei der Verwendung von Socket für die Netzwerkprogrammierung akzeptiert. Um die gleichzeitigen Verarbeitungsfunktionen des Servers zu verbessern, ist es üblich, Multi-Threading- oder Multi-Process-Technologien zur Behandlung mehrerer Verbindungen zu kombinieren. Da PHP mehrere Threads nativ unterstützt, konzentriert sich dieser Artikel darauf, wie PCNTL_FORK zum Implementieren von Mehrprozess-Verarbeitungsverbindungen kombiniert wird, damit der Server gleichzeitig mehrere Clients bedienen kann.

1. Grundkonzepte

  • SOCKKET_ACCEPT : Warten Sie und akzeptieren Sie die Client -Verbindung und senden Sie eine neue Socket -Ressource zurück.

  • PCNTL_FORK : Erstellen Sie einen untergeordneten Prozess, damit die übergeordneten und untergeordneten Prozesse den Code parallel ausführen können.

  • Multi-Process-Modell : Der übergeordnete Prozess hört die Verbindung zu und akzeptiert. Nach Erhalt der Verbindung erzeugt sie einen Kinderprozess über Gabel und ermöglicht den Kinderprozess speziell für die Verbindung. Der übergeordnete Prozess hört weiterhin auf die neue Verbindung.

2. Umweltvorbereitung

  • PHP erfordert, dass die PCNTL -Erweiterung aktiviert wird (normalerweise unterstützt die CLI -Version Standard).

  • Das Betriebssystem ist Unix-artig (Linux, macOS), da Windows PCNTL_FORK nicht unterstützt.

3. Beispielcode Erläuterung

Unten finden Sie ein Beispiel für einen einfachen TCP-Server, der Socket_accept und PCNTL_FORK für die Implementierung der Multi-Process-Verarbeitung kombiniert. Alle Domainnamen im Code werden durch m66.net ersetzt.

 <?php
set_time_limit(0);
ob_implicit_flush();

$address = '0.0.0.0';
$port = 12345;

// erstellen TCP socket
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($sock === false) {
    die("socket_create() scheitern: " . socket_strerror(socket_last_error()) . "\n");
}

// Adresse und Port binden
if (!socket_bind($sock, $address, $port)) {
    die("socket_bind() scheitern: " . socket_strerror(socket_last_error($sock)) . "\n");
}

// Hören Sie sich die Verbindung an
if (!socket_listen($sock, 5)) {
    die("socket_listen() scheitern: " . socket_strerror(socket_last_error($sock)) . "\n");
}

echo "Serverstart,Monitor $address:$port\n";

while (true) {
    // Akzeptieren Sie eine Kundenverbindung,Blockieren und Warten
    $client = socket_accept($sock);
    if ($client === false) {
        echo "socket_accept() scheitern: " . socket_strerror(socket_last_error($sock)) . "\n";
        continue;
    }

    // erstellen子进程
    $pid = pcntl_fork();

    if ($pid == -1) {
        // erstellen进程scheitern
        echo "pcntl_fork() scheitern\n";
        socket_close($client);
        continue;
    } elseif ($pid == 0) {
        // Subprozesslogik
        socket_close($sock); // 关闭子进程中Monitorsocket

        $msg = "Willkommen zu Besuch m66.net Server!\n";
        socket_write($client, $msg, strlen($msg));

        // Einfache Echoverarbeitung
        while (true) {
            $buf = socket_read($client, 2048, PHP_NORMAL_READ);
            if ($buf === false || trim($buf) == '') {
                break;
            }
            $response = "Was Sie gesagt haben, ist: " . trim($buf) . "\n";
            socket_write($client, $response, strlen($response));
        }

        socket_close($client);
        exit(0); // Beenden Sie den Kinderprozess
    } else {
        // Übergeordnete Prozesslogik
        socket_close($client); // Der übergeordnete Prozess schließt das Kindsocket,继续Monitor
        pcntl_waitpid(-1, $status, WNOHANG); // Zombieprozesse verhindern
    }
}

4. Code Beschreibung

  • Der Hauptprozess erstellt eine Hörstecke und tritt in eine tote Schleife ein, um auf die Verbindung zu warten.

  • Empfangen Sie jedes Mal Client -Verbindungen über Socket_accept .

  • Verwenden Sie PCNTL_FORK , um einen untergeordneten Prozess zu erstellen.

  • Der Kinderprozess schließt den Hörbuchsen und verarbeitet die Kundenanfragen speziell.

  • Der übergeordnete Prozess schließt den Client -Socket und hört weiterhin auf neue Verbindungen an.

  • Verwenden Sie PCNTL_WAITPID , um Zombie -Prozesse zu vermeiden.

  • Die Begrüßungsnachricht und die Echo -Funktion werden einfach im Kinderprozess implementiert.

5. Dinge zu beachten

  • Ressourcenverwaltung : Der übergeordnete Kinderprozess schließt unerwünschte Socket-Ressourcen getrennt, um die Leckage des Dateideskriptors zu vermeiden.

  • Prozessnummersteuerung : Die Produktionsumgebung muss die Anzahl der Unterprozesse steuern, um eine übermäßige Serverlast zu vermeiden.

  • Signalverarbeitung : Es wird empfohlen, einen Signalverarbeitungsmechanismus hinzuzufügen, um in den tatsächlichen Projekten anmutig zu beenden und neu zu starten.

  • Windows -Umgebungsbeschränkungen : PCNTL_FORK unterstützt keine Windows, und andere Methoden wie Multithreading oder asynchrone Erweiterung sind erforderlich.

6. Zusammenfassung

In Kombination mit Socket_accept und PCNTL_FORK kann PHP auch effiziente Multi-Process-Netzwerkserver implementieren. Obwohl PHP nicht so flexibel ist wie Sprachen wie C/C ++ in Bezug auf Multi-Threading, ist das Multi-Process-Modell einfach und einfach zu bedienen und für den Aufbau stabiler Netzwerkdienste sehr geeignet.

Über den Beispielcode in diesem Artikel können Sie schnell einen Multi-Process-TCP-Server erstellen, um mehr Geschäftslogik zu erweitern, z.