Socket: cos’è e come funziona
Con socket si intende un oggetto software, il cui compito è quello di indirizzare correttamente i pacchetti di dati fra host. È presente sia nelle comunicazioni che avvengono tramite rete (fra host remoti) sia in quelle locali (Inter-Process Communication).
I socket in comunicazione, in entrambi i casi, formano una coppia (detta pair), che si compone di due valori estremamente importanti: indirizzo e porta. Questi permettono al pacchetto di dati di raggiungere la destinazione corretta, grazie a una connessione logica. Attraverso apposite API, i sistemi operativi abilitano le applicazione all’uso dei socket di rete.
Com’è strutturato un socket address
Disporre di valori come indirizzo e porta in un socket address, è importante per permettere a due interlocutori di dialogare correttamente. I processi in esecuzione su ogni interlocutore (sia esso un server o un client), infatti, sono moltissimi, per questo sapere a quale puntare è cruciale. Per fare ciò si usano le porte, ovvero numeri specifici assegnati a ogni processo.
Un indirizzo socket, dunque, si compone di: un indirizzo IP a 32 bit e un numero di porta a 16 bit. I numeri di porta sono raggruppati in diverse sottocategorie (definite dalla IANA), per facilitarne l’identificazione e la funzione:
- well-known (riservate a protocolli specifici): 20, 23, 25, 80, 110,…;
- non usate: 0;
- riservate per processi well-known: 1-255;
- riservate per altri processi: 256-1023;
- altre applicazioni: 1024-65535.
Il sistema operativo provvede ad assegnare in autonomia i numeri di porta ai processi classificati come non well-known. In questo caso si parla di porte effimere. Un altro aspetto importante dei socket è la famiglia (anche detta dominio). Essa varia a seconda del tipo di protocollo di comunicazione utilizzato, ma quelle che vale la pena citare sono due:
- AF_INET: per la comunicazione tra host remoti, via Internet;
- AF_UNIX: che identifica la comunicazione tra processi locali (più precisamente su macchine Unix). Un altro nome di questa famiglia è, infatti, Unix Domain Socket.
Tipologie di socket e metodo di comunicazione
In ogni famiglia si possono distinguere diverse tipologie di socket, che variano a seconda della modalità di connessione utilizzata. I datagram socket, ad esempio, sono basati sul protocollo UDP e non sono orientati alla connessione (connectionless). Gli stream socket, invece, sono orientati alla connessione e si basano sui più affidabili TCP o SCTP. Esistono poi i raw socket in cui l’header è accessibile a livello applicativo e il livello di trasporto viene bypassato.
Grazie a protocolli sicuri come TCP e SCTP, gli stream socket sono i più affidabili, soprattutto per la comunicazione in rete. Essi garantiscono caratteristiche full-duplex e connection oriented con un flusso di byte di lunghezza variabile. In questo esempio specifico la comunicazione si struttura in diverse fasi:
- il socket viene creato sia nel client che nel server. Il server pone in ascolto il proprio socket mediante una porta specifica;
- la richiesta di connessione viene effettuata dal client verso il server. Se quest’ultimo la accetta si crea la connessione;
- a questo punto il server crea un nuovo socket specifico per il client detto data socket, che viene utilizzato per lo scambio di dati fra i due;
- il client comunica la fine del messaggio al server, che provvede a eliminare l’istanza del data socket e a chiudere la connessione.
I datagram socket basati su UDP sono più veloci rispetto agli stream socket (perché saltano la fase di richiesta di connessione al server), ma anche meno sicuri. In questa tipologia di socket, la comunicazione si struttura in sole tre fasi:
- creazione del socket (senza la necessità di una connessione);
- invio dei dati (il client manda i dati direttamente al server tramite i rispettivi numeri di porta);
- risposta del server (la comunicazione continua in loop finché ci sono dati da inviare).
