dal 2015 - visita n. 3553
php socket parte 4
php socket parte 4

 

Socket stream

Riprendiamo l'esercizio socket01.php, svolto nella parte introduttiva e, intanto, riscriviamolo introducendo una apposita funzione per la gestione dei messaggi d'errore GestErr. Focalizziamo, inoltre, l'attenzione sul fatto che la scrittura dello script è stata molto facilitata dalle apposite estensioni del PHP dedicate ai socket, ossia tutte le funzioni usate che iniziano per socket_ e che ci sono servite per creare, connettere, chiudere i socket, ed altro ancora.

Esecuzione dello script

Dopo aver salvato il codice precedente nella cartella public_html dandogli il nome socket01b.php, lo possiamo mandare in esecuzione direttamente dalla riga di comando di un terminale:

$ php ~/public_html/socket01b.php

ottenendo in risposta:

Socket creato correttamente. 
Connessione attivata. 
Invio messaggio riuscito. 
HTTP/1.0 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Location: http://www.google.it/?gfe_rd=cr&ei=0RXyVIXGLsuG8QfMxYCYBg
Content-Length: 258
Date: Thu, 26 Feb 2015 17:28:48 GMT
Server: GFE/2.0
Alternate-Protocol: 80:quic,p=0.08

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.it/?gfe_rd=cr&ei=0RXyVIXGLsuG8QfMxYCYBg">here</A>.
</BODY></HTML>

Come si può facilmente constatare, il risultato ottenuto è esattamente lo stesso dell'esempio precedente.


La funzione interna PHP fsockopen

Ma, a questo punto vogliamo far notare che per risolvere i problemi con i socket non è necessario utilizzare le estensioni PHP che abbiamo usato finora. Lo stesso problema di prima può essere risolto utilizzando la tecnica dei file stream.


In questo caso la funzione fsockopen crea contemporaneamente il socket e la connessione, e non è necessario conoscere l'indirizzo IP ma è sufficiente specificare il nome del dominio. La funzione fwrite invia il messaggio e la funzione fgets riceve i dati. Molto semplice e simile alle operazioni di lettura/scrittura da flussi di file.

Esecuzione dello script

Dopo aver salvato il codice precedente nella cartella public_html dandogli il nome socket01c.php, lo possiamo mandare in esecuzione direttamente dalla riga di comando di un terminale:

$ php ~/public_html/socket01c.php

ottenendo in risposta:

HTTP/1.0 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Location: http://www.google.it/?gfe_rd=cr&ei=wCvyVOnuDKms8wfBs4FY
Content-Length: 258
Date: Thu, 26 Feb 2015 17:28:48 GMT
Server: GFE/2.0
Alternate-Protocol: 80:quic,p=0.08

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.it/?gfe_rd=cr&ei=wCvyVOnuDKms8wfBs4FY">here</A>.
</BODY></HTML>

Funzioni interne del PHP per i socket

Il lavoro precedente ha prodotto una connessione di rete senza la necessità di utilizzare necessariamente le estensioni di PHP per i socket. Naturalmente se le estensioni sono state aggiunte è stato fatto per rendere il PHP più completo, ma il linguaggio stesso consente tuttavia di portare a termine le operazioni più tipiche con i socket semplicemente sfruttando alcune sue funzioni interne.

Nell'esempio precedente è stato creato un socket TCP, invece per creare un socket UDP, sempre con l'uso della funzione fsockopen, bisogna specificare nei suoi primi 2 parametri il cosiddetto socket stream wrapper, come qui di seguito indicato:

$fp = fsockopen("udp://127.0.0.1", 13, $errno, $errstr);

Nel socket stream wrapper per TCP naturalmente ci sarà tcp:// al posto di udp://, mentre la sintassi generale sarà:

$protocol://$host:$port

L'uso delle funzioni interne costituisce, quando possibile, una alternativa facile e veloce per lavorare con i socket, senza caricare il PHP di altro lavoro supplementare. Esiste un'altra funzione, chiamata stream_socket_client che svolge più o meno lo stesso lavoro di fsockopen.

$fp = stream_socket_client("tcp://www.google.it:80", $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />n";
} 

La sua struttura è quasi identica a quella di fsockopen, tranne per il fatto che il numero di porta viene passato assieme al primo parametro, separato dai due punti.


Un'altra versione di server

Le funzioni interne del PHP consentono anche di gestire dei server, come viene fatto con il codice seguente che mette in attesa un semplice server per rispondere alle richieste di un client.

Esecuzione dello script

Dopo aver salvato il codice precedente nella cartella public_html dandogli il nome stream01.php, lo possiamo mandare in esecuzione direttamente dalla riga di comando di un terminale:

$ php ~/public_html/stream01.php

ottenendo in risposta:

In attesa delle connessioni...  

Apriamo adesso un altro terminale e digitiamo:

$ telnet localhost 4444

otterremo in risposta:

Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

che ci avverte dell'avvenuta connessione. Il nostro semplice server è in grado di svolgere soltanto il servizio di eco, un client per volta. Infatti inviando dal nostro terminale client dei messaggi otterremo soltanto la replica del messaggio inviato. Non solo, ma se apriamo un terzo terminale come client telnet, quest'ultimo sarà servito soltanto quando avremo chiuso il precedente.

Attivazione di connessioni multiple

Quindi occorrerà riscrivere meglio il codice per consentire la gestione di connessioni multiple.

Esecuzione dello script

Dopo aver salvato il codice precedente nella cartella public_html dandogli il nome stream02.php, lo possiamo mandare in esecuzione direttamente dalla riga di comando di un terminale:

$ php ~/public_html/stream02.php

ottenendo in risposta:

In attesa delle connessioni...  

Questa volta aprendo vari terminali telnet ognuno di essi verrà servito subito ed in maniera indipendente dagli altri. L'apertura e la chiusura dei vari terminali verrà segnalata regolarmente sul terminale del server. Una tipica schermata del terminale del server potrebbe essere simile alla seguente:

In attesa delle connessioni...
Connessione accettata da 127.0.0.1:34391
TOTALE client connessi: 1
Connessione accettata da 127.0.0.1:34393
TOTALE client connessi: 2
Connessione accettata da 127.0.0.1:34395
TOTALE client connessi: 3
Un client si è disconnesso. 
TOTALE client connessi: 2
Un client si è disconnesso. 
TOTALE client connessi: 1

L'output precedente mostra che prima si sono collegati 3 client e poi 2 di essi si sono scollegati.


Punto della situazione

In questa sezione abbiamo imparato come:


















Menù
Introduzione
Ambiente di sviluppo
intro php-01
tag e commenti php-02
variabili e tipi php-03
operatori php-04
php IF esercizi
php FOR esercizi
php objects intro
php objects parte 1
php objects parte 2
php objects parte 3
php objects parte 4
php objects parte 5
CLIL
php socket intro
php socket parte 1
php socket parte 2
php socket parte 3
php socket parte 4
php socket parte 5
php socket parte 6
php socket extra
linux netcat


MiniGuida PHP
Guida Ufficiale PHP (en)
Form Base
Flat DataBase
Pagine Protette
mySQL



La ricchezza del mio cuore è infinita come il mare, così profondo il mio amore; più te ne dò, più ne ho, perché entrambi sono infiniti.
William Shakespeare

Valid CSS!
pagina generata in 0.003 secondi