dal 2015 - visita n. 2207
php socket intro
php socket intro

 

Ottenere l'indirizzo IP dal nome del dominio

Adesso è arrivato il momento di far svolgere al server alcune attività tramite i socket. Ma prima di andare avanti ci sono alcuni argomenti collaterali che devono essere compresi nel caso ce ne fosse la necessità.

Quando ci si collega ad un host remoto è necessario poter disporre de suo indirizzo IP. La funzione gethostbyname è quella che fa al nostro scopo, essa prende il nome del dominio come parametro e ne restituisce l'indirizzo IP.

$ip_address = gethostbyname("www.google.it");
// = 173.194.75.104

Quindi con il codice precedente, dal nome di qualsiasi dominio, si può trovare il suo indirizzo IP, e con questo si può stabilire una connessione utilizzando un socket.


Programmazione di un server

Occupiamoci quindi delle attività riguardanti i server, i quali svolgono essenzialmente i seguenti lavori:


Bind di un socket

Abbiamo già visto come aprire un socket, occupiamoci adesso di vedere come si effettua il bind.

La funzione socket_bind è quella che serve per legare un socket ad un particolare indirizzo e ad una porta. Ha bisogno di una struttura sockaddr_in simile a quella della funzione socket_connect.

if (!($sock = socket_create(AF_INET, SOCK_STREAM, 0))) {
	$errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);    
    die("Creazione del socket non riuscita: [$errorcode] $errormsg \n");
}
echo "Socket creato correttamente. \n";

// Bind del socket con l'indirizzo e la porta
if ( !socket_bind($sock, "127.0.0.1" , 5000) ) {
	$errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);    
    die("Bind non riuscito: [$errorcode] $errormsg \n");
}
echo "Bind effettuato con successo. \n";

Una volta realizzato il bind si può procedere all'ascolto delle connessioni. Avendo legato il socket a quel particolare indirizzo IP ed a quel numero di porta, ci assicuriamo che tutti i dati in entrata diretti a quel numero di porta vengono ricevuti da questa applicazione.

Questo rende evidente che non si possono avere 2 socket legati alla stessa porta, ma ci sono delle eccezioni a questa regola, di cui ci occuperemo successivamente.


Ascolto di connessioni

Dopo aver vincolato un socket ad una porta, la prossima cosa da fare è di mettersi in ascolto per le connessioni. Per questo occorre mettere il socket in modalità di ascolto. Per raggiungere lo scopo si utilizza la funzione socket_listen, aggiungendo allo script la riga seguente.

// Impostazione in ascolto
socket_listen ($sock , 10)

Il secondo parametro della funzione socket_listen viene chiamata backlog e controlla il numero di connessioni in ingresso che vengono tenute in "attesa", se il programma è già occupato. Quindi specificando il valore 10 significa che se ci sono già 10 collegamenti in attesa di essere processati allora la richiesta di connessione per l'11ma viene respinta. Questo risulterà più chiaro dopo aver visto la funzione socket_accept.


Accettare una connessione

La parte principale del lavoro consiste nell'accettare le nuove connessioni, questo si realizza tramite la funzione socket_accept.

Esecuzione dello script

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

$ php ~/public_html/socket02.php

ottenendo in risposta:

Socket creato correttamente.
Bind del socket OK.
Ascolto del socket OK.
In attesa dell'arrivo delle connessioni...

Adesso il programma è in attesa di connessioni in ingresso sulla porta 5000. Non chiudere il programma e lasciarlo in esecuzione. Adesso un client sarà in grado di connettersi ad esso su questa porta, e per farlo utilizzeremo telnet come programma di test. Aprire un secondo terminale e digitare:

$ telnet localhost 5000

Immediatamente sul secondo terminale arriverà la risposta:

Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.

Mentre sul primo terminale si vedrà il messaggio:

Client 127.0.0.1 : 38168 risulta collegato.

Quanto accaduto dimostra come il client si sia connesso al server. Provare i passaggi precedenti fino ad ottenere un funzionamento perfetto.

Nota
La funzione socket_getpeername viene utilizzata per ottenere i dettagli relativi al client che è collegato al server tramite un determinato socket.


Nell'esempio precedente dopo aver accettato una connessione in entrata l'abbiamo chiusa immediatamente. Questo non è molto produttivo, ci sono tante cose che si possono fare dopo aver stabilito una connessione. Dopotutto il collegamento è stato effettuato con lo scopo di comunicare, quindi di consentire di rispondere al client.

La funzione socket_write consente al server di scrivere qualcosa sul socket in modo che il client la possa vedere. Ecco un esempio:

Esecuzione dello script

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

$ php ~/public_html/socket03.php

ottenendo in risposta:

Socket creato correttamente.
Bind del socket OK.
Ascolto del socket OK.
In attesa dell'arrivo delle connessioni...

Mentre il server gira su un terminale, apriamo un secondo terminale e facciamo girare il client telnet:

$ telnet localhost 5000

Immediatamente sul secondo terminale arriverà la risposta:

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

mentre sul primo terminale arriverà il messaggio di conferma:

Client 127.0.0.1 : 35181 risulta collegato.

Ancora sul secondo terminale digitiamo un messaggio, seguito da [Invio]:

$ ciao a tutti

ottenendo in risposta:

OK ... ciao a tutti
Connection closed by foreign host.

Mentre sul primo terminale verrà chiusa la connessione.

Abbiamo visto, quindi, come il client telnet abbia ricevuto una risposta dal server, e come la connessione sia stata chiusa subito dopo, per il solo fatto che il programma server termina dopo aver accettato un messaggio e spedito una risposta. Invece un server come www.google.it rimane sempre in ascolto per accettare delle connessioni in entrata. Ciò significa che un server dovrebbe essere sempre in esecuzione. D'altra parte il significato della parola server è proprio quello di servire.


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



Bisogna essere fermi per temperamento e flessibili per riflessione.
L. de Vauvenargues

Valid CSS!
pagina generata in 0.001 secondi