Suche…


TCP-Client-Socket

Socket erstellen, der das TCP (Transmission Control Protocol) verwendet

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

Stellen Sie sicher, dass der Socket erfolgreich erstellt wurde. Die onSocketFailure Funktion stammt aus dem Beispiel zur Behandlung von onSocketFailure in diesem Thema.

if(!is_resource($socket)) onSocketFailure("Failed to create socket");

Verbinden Sie den Sockel mit einer angegebenen Adresse

Die zweite Zeile schlägt fehl, wenn die Verbindung fehlgeschlagen ist.

socket_connect($socket, "chat.stackoverflow.com", 6667)
        or onSocketFailure("Failed to connect to chat.stackoverflow.com:6667", $socket);

Daten an den Server senden

Die Funktion socket_write sendet Bytes über einen Socket. In PHP wird ein Byte-Array durch eine Zeichenfolge dargestellt, die normalerweise für die Codierung unempfindlich ist.

socket_write($socket, "NICK Alice\r\nUSER alice 0 * :Alice\r\n");

Daten vom Server empfangen

Das folgende Snippet empfängt einige Daten vom Server mithilfe der Funktion socket_read .

Das Übergeben von PHP_NORMAL_READ als dritten Parameter liest bis zu einem \r / \n Byte. Dieses Byte ist im Rückgabewert enthalten.

Das Übergeben von PHP_BINARY_READ liest die erforderliche Datenmenge aus dem Stream.

Wenn socket_set_nonblock aufgerufen wurde und PHP_BINARY_READ verwendet wird, gibt socket_read sofort false . Ansonsten blockiert die Methode, bis genügend Daten (um die Länge im zweiten Parameter zu erreichen oder ein Zeilenende zu erreichen) empfangen werden oder der Socket geschlossen ist.

In diesem Beispiel werden Daten von einem vermeintlichen IRC-Server gelesen.

while(true) {
    // read a line from the socket
    $line = socket_read($socket, 1024, PHP_NORMAL_READ);
    if(substr($line, -1) === "\r") {
        // read/skip one byte from the socket
        // we assume that the next byte in the stream must be a \n.
        // this is actually bad in practice; the script is vulnerable to unexpected values
        socket_read($socket, 1, PHP_BINARY_READ);
    }

    $message = parseLine($line);
    if($message->type === "QUIT") break;
}

Steckdose schließen

Durch das Schließen des Sockets werden der Socket und die zugehörigen Ressourcen freigegeben.

socket_close($socket);

TCP-Server-Socket

Socket-Erstellung

Erstellen Sie einen Socket, der das TCP verwendet. Es ist das gleiche wie das Erstellen eines Client-Sockets.

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

Socket-Bindung

Binden Sie Verbindungen von einem bestimmten Netzwerk (Parameter 2) für einen bestimmten Port (Parameter 3) an den Socket.

Der zweite Parameter ist normalerweise "0.0.0.0" , wodurch Verbindungen von allen Netzwerken akzeptiert werden. Es kann auch

Eine häufige Fehlerursache von socket_bind besteht darin, dass die angegebene Adresse bereits an einen anderen Prozess gebunden ist . Andere Prozesse werden normalerweise abgebrochen (normalerweise manuell, um zu verhindern, dass kritische Prozesse versehentlich abgebrochen werden), so dass die Steckdosen freigegeben werden.

socket_bind($socket, "0.0.0.0", 6667) or onSocketFailure("Failed to bind to 0.0.0.0:6667");

Stellen Sie eine Steckdose für das Abhören ein

socket_listen Sie den Socket eingehende Verbindungen mithilfe von socket_listen . Der zweite Parameter ist die maximale Anzahl von Verbindungen, die das Einreihen in die Warteschlange zulassen, bevor diese akzeptiert werden.

socket_listen($socket, 5);

Verbindung handhaben

Ein TCP-Server ist eigentlich ein Server, der untergeordnete Verbindungen verarbeitet. socket_accept erstellt eine neue socket_accept Verbindung.

$conn = socket_accept($socket);

Die Datenübertragung für eine Verbindung von socket_accept ist die gleiche wie für einen TCP-Client-Socket .

Wenn diese Verbindung geschlossen werden soll, rufen Sie socket_close($conn); direkt. Dies hat keinen Einfluss auf den ursprünglichen TCP-Server-Socket.

Server schließen

Auf der anderen Seite socket_close($socket); sollte aufgerufen werden, wenn der Server nicht mehr verwendet wird. Dadurch wird auch die TCP-Adresse freigegeben, sodass andere Prozesse an die Adresse binden können.

Behandlung von Socketfehlern

socket_last_error kann verwendet werden, um die Fehler-ID des letzten Fehlers von der Sockets-Erweiterung socket_last_error .

socket_strerror kann die ID in vom Menschen lesbare Zeichenketten konvertiert werden.

function onSocketFailure(string $message, $socket = null) {
    if(is_resource($socket)) {
        $message .= ": " . socket_strerror(socket_last_error($socket));
    }
    die($message);
}

UDP-Server-Socket

Ein UDP-Server (User Datagram Protocol) ist im Gegensatz zu TCP nicht Stream-basiert. Es ist paketbasiert, dh ein Client sendet Daten in Einheiten, die "Pakete" genannt werden, an den Server, und der Client identifiziert Clients anhand ihrer Adresse. Es gibt keine integrierte Funktion, die verschiedene vom selben Client gesendete Pakete in Beziehung setzt (im Gegensatz zu TCP, bei dem Daten desselben Clients von einer bestimmten, von socket_accept erstellten Ressource socket_accept ). Es kann angenommen werden, dass eine neue TCP-Verbindung jedes Mal akzeptiert und geschlossen wird, wenn ein UDP-Paket ankommt.

UDP-Server-Socket erstellen

$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

Einen Socket an eine Adresse binden

Die Parameter sind die gleichen wie für einen TCP-Server.

socket_bind($socket, "0.0.0.0", 9000) or onSocketFailure("Failed to bind to 0.0.0.0:9000", $socket);

Paket senden

Diese Zeile sendet $data in einem UDP-Paket an $address : $port .

socket_sendto($socket, $data, strlen($data), 0, $address, $port);

Ein Paket erhalten

Das folgende Snippet versucht, UDP-Pakete clientindiziert zu verwalten.

$clients = [];
while (true){
    socket_recvfrom($socket, $buffer, 32768, 0, $ip, $port) === true
            or onSocketFailure("Failed to receive packet", $socket);
    $address = "$ip:$port";
    if (!isset($clients[$address])) $clients[$address] = new Client();
    $clients[$address]->handlePacket($buffer);
}

Server schließen

socket_close kann für die UDP-Server-Socket-Ressource verwendet werden. Dadurch wird die UDP-Adresse freigegeben, sodass andere Prozesse an diese Adresse binden können.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow