Esercitazioni per il laboratorio di Informatica e Sistemi
a cura del prof. Francesco Pecoraro
Esercizi di programmazione in php
Socket in PHP
Riferimento

In questo esempio viene costruito un semplice programma Server, che sfruttando una connessione TCP, accetta una stringa da un programma client e la restituisce al client.

Vengono assegnati i valori relativi all'indirizzo IP del computer e il numero di porta su cui sarà in ascolto il programma Server. Il numero di porta può essere un qualsiasi valore, non usato da nessun'altra applicazione, compreso tra 1 e 65.535.
<?php
$host = "192.168.1.99";
$port = 1234;
Il server Web concede ad uno script un tempo massimo di esecuzione, trascorso tale intervallo lo script viene eliminato. Il programma server resterà in attesa di ricevere richieste di connessione, quindi potrebbe attendere un tempo indefinito superiore al limite ammesso. Quindi per evitare l'errore di time out, si disabilita il controllo.
set_time_limit(0);
Creazione del socket tramite la funzione socket_create.
Questa funzione restituisce un gestore del socket che verrà, usato in tutte le funzioni successive che faranno riferimento al socket.
$socket = socket_create(AF_INET, SOCK_STREAM, 0) 
	  or 
	  die("Non riesco a creare il socket\n");
Il parametro AF_INET specifica il dominio, mentre il parametro SOCK_STREAM imposta il protocollo TCP.

Se invece si volesse creare un socket che fa uso del protocollo UDP, il secondo parametro deve essere modificato come nella seguente chiamata di funzione:

$socket = socket_create(AF_INET, SOCK_DGRAM, 0)
or
die("Non riesco a creare il socket\n");

Dopo aver creato il gestore del socket bisogna effettuare il collegamento sulla porta specificata, tramite la chiamata di funzione: socket_bind().
$esito = socket_bind($socket, $host, $port) 
	  or 
          die("impossibile stabilire la connessione al socket\n");

A questo punto il socket è stato creato e collegato alla porta. L'operazione successiva consiste nel mettere il programma in attesa di ricevere richieste di connessioni. Il PHP consente di affidare al socket il compito di ascoltare le richieste di apertura di connessione tramite la funzione socket_listen(). Questa permette anche di specificare come secondo parametro il numero di richieste di connessione da accodare. Nell'esempio che segue il secondo parametro vale 3.

$esito = socket_listen($socket, 3) 
	  or 
	  die("Impossibile impostare il socket in ascolto\n");

Il server non sta svolgendo ancora nessuna operazione, a parte quella di aspettare le richieste di connessione. Ma quando arriverà una richiesta di connessione da parte di un client il server, tramite la funzione socket_accept(), comunicherà al client la disponibilità a stabilire un trasferimento di pacchetti, creando un apposito socket riservato a gestire la comunicazione tra il client e il server.

$packDati = socket_accept($socket) 
	 or 
	 die("Impossibile accettare altre connessioni\n");

La funzione socket_accept restituisce il socket che verrà usato per trasferire i pacchetti.

Il server, dopo aver accettato la richiesta di apertura connessione, passa in attesa di ricevere pacchetti dati. Il pacchetto ricevuto viene letto tramite la funzione socket_read() e trasferito nella variabile $datiLetti.

$datiLetti = socket_read($packDati, 1024) 
	 or 
	 die("Non riesco a leggere pacchetti\n");

Il secondo parametro della funzione socket_read() specifica il numero di byte da leggere. Questo valore può essere usato per limitare la dimensione dei dati da leggere dal pacchetto.

Notare che la funzione socket_read() continua a leggere dati dal client fino a quando incontra uno dei caratteri carriage return (\n), tab (\t) o un carattere \0 (fine stringa). Questo carattere viene interpretato come carattere di fine input.

La fase di ricezione è terminata, il server deve elaborare i dati ricevuti dal client. Nell'esempio, l'elaborazione consiste nell'invertire la stringa ricevuta e ripeterla al client. Ciò è, compiuto tramite la funzione socket_write(), che deposita dati nel pacchetto e spedisce il pacchetto al client tramite il socket di comunicazione.

$datiInviati = strrev($datiLetti) . "\n";
socket_write($packDati, $datiInviati, strlen ($datiInviati)) 
	or 
	die("Non riesco a scrivere nel pacchetto di risposta\n");
La funzione socket_write() richiede tre parametri: un riferimento al socket, la stringa da inviare, e il numero di byte che devono essere scritti.

Siccome i due interlocutori non hanno altro da scambiarsi, i socket vengono eliminati tramite la funzione socket_close().

socket_close($packDati);
socket_close($socket);
?>