Ricerca…


Socket client TCP

Creazione di un socket che utilizza TCP (Transmission Control Protocol)

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

Assicurarsi che il socket sia stato creato correttamente. La funzione onSocketFailure deriva da Gestione errori di socket in questo argomento.

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

Collegare il socket a un indirizzo specificato

La seconda riga fallisce con garbo se la connessione fallisce.

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

Invio di dati al server

La funzione socket_write invia byte attraverso un socket. In PHP, una matrice di byte è rappresentata da una stringa, che normalmente non è sensibile alla codifica.

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

Ricezione di dati dal server

Lo snippet seguente riceve alcuni dati dal server utilizzando la funzione socket_read .

Passando a PHP_NORMAL_READ come il terzo parametro si legge fino a un byte \r / \n e questo byte è incluso nel valore restituito.

Passando PHP_BINARY_READ , al contrario, legge la quantità richiesta di dati dallo stream.

Se socket_set_nonblock stato chiamato in precedenza e PHP_BINARY_READ viene utilizzato, socket_read restituirà false immediatamente. In caso contrario, il metodo blocca fino a quando non vengono ricevuti dati sufficienti (per raggiungere la lunghezza nel secondo parametro o per raggiungere una fine riga) o il socket è chiuso.

Questo esempio legge i dati da un presunto server IRC.

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;
}

Chiudere la presa

La chiusura del socket libera il socket e le sue risorse associate.

socket_close($socket);

Socket del server TCP

Creazione di prese

Creare un socket che utilizza il TCP. È come creare un socket client.

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

Attacco presa

Collega le connessioni da una data rete (parametro 2) per una porta specifica (parametro 3) alla presa.

Il secondo parametro è solitamente "0.0.0.0" , che accetta la connessione da tutte le reti. Io posso anche

Una causa comune di errori da socket_bind è che l'indirizzo specificato è già associato a un altro processo . Di solito, altri processi vengono uccisi (di solito manualmente per evitare di uccidere accidentalmente processi critici) in modo che i socket vengano liberati.

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

Imposta un socket per l'ascolto

Fai in modo che il socket ascolti le connessioni in entrata usando socket_listen . Il secondo parametro è il numero massimo di connessioni per consentire l'accodamento prima che vengano accettate.

socket_listen($socket, 5);

Gestione della connessione

Un server TCP è in realtà un server che gestisce le connessioni figlio. socket_accept crea una nuova connessione figlio.

$conn = socket_accept($socket);

Il trasferimento dati per una connessione da socket_accept è uguale a quello per un socket client TCP .

Quando questa connessione deve essere chiusa, chiama socket_close($conn); direttamente. Ciò non influirà sul socket del server TCP originale.

Chiusura del server

D'altra parte, socket_close($socket); dovrebbe essere chiamato quando il server non è più utilizzato. Ciò libererà anche l'indirizzo TCP, consentendo ad altri processi di collegarsi all'indirizzo.

Gestione degli errori di socket

socket_last_error può essere utilizzato per ottenere l'ID errore dell'ultimo errore dall'estensione socket.

socket_strerror può essere utilizzato per convertire l'ID in stringhe leggibili dall'uomo.

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

Socket del server UDP

Un server UDP (user datagram protocol), a differenza di TCP, non è basato sul flusso. È basato su pacchetti, ovvero un client invia i dati in unità denominate "pacchetti" al server e il client identifica i client in base al loro indirizzo. Non esiste una funzione incorporata che colleghi diversi pacchetti inviati dallo stesso client (diversamente dal TCP, dove i dati dallo stesso client sono gestiti da una risorsa specifica creata da socket_accept ). Può essere pensato come una nuova connessione TCP è accettata e chiusa ogni volta che arriva un pacchetto UDP.

Creazione di un socket del server UDP

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

Associazione di un socket a un indirizzo

I parametri sono gli stessi di un server TCP.

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

Invio di un pacchetto

Questa riga invia $data in un pacchetto UDP a $address : $port .

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

Ricevere un pacchetto

Lo snippet seguente tenta di gestire i pacchetti UDP in modo indicizzato dal client.

$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);
}

Chiusura del server

socket_close può essere utilizzato sulla risorsa socket del server UDP. Questo libererà l'indirizzo UDP, consentendo ad altri processi di collegarsi a questo indirizzo.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow