Forum und email

Funzioni relative ai Socket

Introduzione

Questa estensione implementa una interfaccia a basso livello verso i socket, fornendo la possibilità di agire sia come server sia come client.

Per un esempio di una interfaccia generica lato client, vedere stream_socket_client(), stream_socket_server(), fsockopen() e pfsockopen().

Per l'utilizzo di queste funzioni, è importante ricordare che molte di esse hanno il medesimo nome della loro controparte in C, ma spesso hanno dichiarazioni differenti. Ricordarsi di leggere la descrizione per evitare confusione.

Per chi non ha familiarità con la programmazione dei socket, può trovare utili informazioni nelle pagine del manuale di Unix, ed inoltre sul web si può trovare diversi tutorial sulla programmazione dei socket in C, molti dei quali possono essere utilizzati, con lievi modifiche, nella programmazione dei socket in PHP. Il link » Unix Socket FAQ può essere un buon punto di partenza.

Avviso

Questo modulo è SPERIMENTALE. Ovvero, il comportamento di queste funzioni, i nomi di queste funzioni, in definitiva tutto ciò che è documentato qui può cambiare nei futuri rilasci del PHP senza preavviso. Siete avvisati, l'uso di questo modulo è a vostro rischio.

Requisiti

Non sono necessarie librerie esterne per utilizzare questo modulo.

Installazione

Le funzioni relative ai socket qui descritte sono parte di una estensione del PHP che occorre abilitare durante la fase di compila usando l'opzione --enable-sockets del comando configure.

Nota: Il supporto all'IPv6 è stato aggiunto in PHP 5.0.0.

Configurazione di Runtime

Questa estensione non definisce alcuna direttiva di configurazione in php.ini

Tipi di risorse

Questa estensione non definisce alcun tipo di risorsa.

Costanti predefinite

Queste costanti sono definite da questa estensione e sono disponibili solo se l'estensione è stata compilata nel PHP o se è stata caricata dinamicamente a runtime.

AF_UNIX (integer)
AF_INET (integer)
AF_INET6 (integer)
SOCK_STREAM (integer)
SOCK_DGRAM (integer)
SOCK_RAW (integer)
SOCK_SEQPACKET (integer)
SOCK_RDM (integer)
MSG_OOB (integer)
MSG_WAITALL (integer)
MSG_PEEK (integer)
MSG_DONTROUTE (integer)
SO_DEBUG (integer)
SO_REUSEADDR (integer)
SO_KEEPALIVE (integer)
SO_DONTROUTE (integer)
SO_LINGER (integer)
SO_BROADCAST (integer)
SO_OOBINLINE (integer)
SO_SNDBUF (integer)
SO_RCVBUF (integer)
SO_SNDLOWAT (integer)
SO_RCVLOWAT (integer)
SO_SNDTIMEO (integer)
SO_RCVTIMEO (integer)
SO_TYPE (integer)
SO_ERROR (integer)
SOL_SOCKET (integer)
PHP_NORMAL_READ (integer)
PHP_BINARY_READ (integer)
SOL_TCP (integer)
SOL_UDP (integer)

Errori dei socket

L'estensione dei socket è stata scritta per fornire una pratica interfaccia ai potenti socket BSD. Si noti che le funzioni girano correttamente sia su sistemi Unix sia su sistemi Win32. Quasi tutte le funzioni dei socket possono fallire in certe situazioni e quindi generare un messaggio di tipo E_WARNING per descrivere l'errore. Qualche volta ciò non accade secondo le aspettative dello sviluppatore. Ad esempio la funzione socket_read() improvvisamente può generare un messaggio di E_WARNING a causa di una interruzione inaspettata della connessione. E' prassi comune sopprimere i messaggi di warning con l'operatore @ ed intercettare il codice dell'errore utilizzando la funzione socket_last_error(). Si può anche richiamare la funzione socket_strerror() con questo codice di errore per avere un testo descrittivo del problema. Per maggiori dettagli vedere la descrizione delle funzioni.

Nota: I messaggi E_WARNING generati dal modulo dei socket sono in inglese, mentre i messaggi di errore recuperati dipendono dalle correnti impostazioni locali (LC_MESSAGES):

Warning - socket_bind() unable to bind address [98]: Die Adresse wird bereits verwendet

Esempi

Example#1 Esempio di programma con i socket: semplice server TCP/IP

Questo esempio illustra un semplice server. Occorre modificare le variabili address e port per adeguarle ai parametri della macchina su cui sarà eseguito. Ci si può connettere al server con un comando simile a telnet 192.168.1.53 10000 (dove l'indirizzo e la porta devono essere uguali a quanto indicato nel setup). Qualsiasi lettera sarà digitata, verrà visualizzata sul server e sul client. Per disconnettersi, digitare 'quit'.

#!/usr/local/bin/php -q
<?php
error_reporting
(E_ALL);

/* Si indica allo script di non uscire mentre attende una connessione */
set_time_limit(0);

/* Abilita lo scarico dell'output così si è in grado di vedere cosa passa
 * non appena arrivano i dati al server. */
ob_implicit_flush();

$address '192.168.1.53';
$port 10000;

if ((
$sock socket_create(AF_INETSOCK_STREAMSOL_TCP)) < 0) {
    echo 
"socket_create() fallito: motivo: " socket_strerror($sock) . "\n";
}

if ((
$ret socket_bind($sock$address$port)) < 0) {
    echo 
"socket_bind() fallito: motivo: " socket_strerror($ret) . "\n";
}

if ((
$ret socket_listen($sock5)) < 0) {
    echo 
"socket_listen() fallito: motivo: " socket_strerror($ret) . "\n";
}

do {
    if ((
$msgsock socket_accept($sock)) < 0) {
        echo 
"socket_accept() fallito: motivo: " socket_strerror ($msgsock) . "\n";
        break;
    }
    
/* Invio delle istruzioni */
    
$msg "\nBenvenuti al server di test in PHP. \n" .
        
"Per uscire, digitare 'quit'. Per chiudere il server digitare 'shutdown'.\n";
    
socket_write($msgsock$msgstrlen($msg));

    do {
        if (
FALSE === ($buf socket_read($msgsock2048PHP_NORMAL_READ))) {
            echo 
"socket_read() fallito: motivo: " socket_strerror($ret) . "\n";
            break 
2;
        }
        if (!
$buf trim($buf)) {
            continue;
        }
        if (
$buf == 'quit') {
            break;
        }
        if (
$buf == 'shutdown') {
            
socket_close($msgsock);
            break 
2;
        }
        
$talkback "PHP: Testo scritto '$buf'.\n";
        
socket_write($msgsock$talkbackstrlen $talkback));
        echo 
"$buf\n";
    } while (
true);
    
socket_close($msgsock);
} while (
true);

socket_close($sock);
?>

Example#2 Esempio di programma con i socket: semplice client TCP/IP

In questo esempio sarà illustrato un semplice client HTTP. Questo, molto semplicemente, si collega ad un server, invia una richiesta HEAD, visualizza la risposta ed esce.

<?php
error_reporting
(E_ALL);

echo 
"<h2>Connessione TCP/IP </h2>\n";

/* Ottiene la porta per il servizio WWW. */
$service_port getservbyname('www''tcp');

/* Ottiene l'indirizzo IP per il server cercato. */
$address gethostbyname('www.php.net');

/* Crea un socket TCP/IP. */
$socket socket_create(AF_INETSOCK_STREAMSOL_TCP);
if (
$socket 0) {
    echo 
"socket_create() fallito: motivo: " socket_strerror($socket) . "\n";
} else {
    echo 
"OK.\n";
}

echo 
"Tentativo di connessione a '$address' sulla porta '$service_port'...";
$result socket_connect($socket$address$service_port);
if (
$result 0) {
    echo 
"socket_connect() fallito.\nMotivo: ($result) " socket_strerror($result) . "\n";
} else {
    echo 
"OK.\n";
}
$in "HEAD / HTTP/1.1\r\n"
$in .= "Host: www.example.com\r\n"
$in .= "Connection: Close\r\n\r\n";
$out '';

echo 
"Invio HTTP HEAD...";
socket_write($socket$instrlen ($in));
echo 
"OK.\n";

echo 
"Lettura della risposta:\n\n";
while (
$out socket_read($socket2048)) {
    echo 
$out;
}

echo 
"Chiusura del socket...";
socket_close($socket);
echo 
"OK.\n\n";
?>

Indice dei contenuti