Nel presente articolo saranno affrontati i seguenti argomenti in maniera introduttiva:
- Cos'è un socket
- Come si usa un socket con Java
- Semplice applicativo per comunicazione tramite socket sviluppato in Java
- Cenni sulla sicurezza dei dati
- Conclusioni
Cos'è un socket
Domanda fondamentale per poter approfondire l'argomento è: cos'è un socket? Un socket è una porta di comunicazione tra due computer che utilizzino il protocollo TCP/IP (vedi in seguito). Tramite queste porte è possibile scambiare messaggi in maniera bidirezionale. I provider Internet devono necessariamente dedicare alcune porte della loro macchina ad alcune azioni fondamentali. Ad esempio, le porte socket dedicate alla posta sono la 25 (per SMTP) e la 110 (per POP3). Il proxy generalmente è sulla porta 8080, Telnet sulla 23, FTP sulla 21 e così via. È naturalmente possibile usare porte lasciate libere per i propri scopi, previo accordo con il provider, che potrebbe non gradire l'intrusione e chiudervi l'applicativo. Non provate a utilizzare una delle porte dette precedentemente: otterreste un messaggio di errore e nient'altro.
Un esempio, che si vedrà dettagliatamente in seguito, è quello di usare una porta per scambiare messaggi come se fosse un telefono. Da notare il fatto che, se si hanno due o più computer collegati in rete e si usa il protocollo TCP/IP, è possibile usare i socket come se si fosse collegati a Internet. Per gli amanti della precisione dirò che è vero il contrario: su Internet si usano le porte esattamente come se fossimo tra due o più computer nella stessa stanza.
Detto ciò, si può ragionevolmente pensare di entrare nel dettaglio e di far comunicare due programmi tramite socket. È però fondamentale una constatazione. Come nella posta elettronica, se il messaggio tra due applicativi passa solo da un provider - i due applicativi sono sulla stessa macchina, oppure uno è sul provider e l'altro su un computer collegato fisicamente ad esso - la comunicazione è intercettabile solo dal provider stesso, che però generalmente non ha interesse a farlo. Se invece si passa attraverso la rete, con un'applicazione su un provider e l'altra su un altro, allora si può lasciar perdere il discorso sulla segretezza. Non esiste segretezza su Internet!
Per ovviare a questo inconveniente si possono criptare i messaggi, cosicché, se qualcuno li intercetta, non sia poi in grado di leggerli. Per fare ciò si può usare un sistema di criptatura fatto da sé, appoggiarsi alle sicurissime routine di PGP, o usare le SSL (Secure Socket Layer) di cui si accennerà in seguito.
Breve teoria di TCP/IP
Bene, a questo punto è doveroso parlare, almeno in termini generali, di cosa sia il protocollo TCP/IP, a cosa serva, quali siano le sue caratteristiche e come usarlo. Per prima cosa: cos'è un protocollo di comunicazione e, in particolare, TCP/IP? Un protocollo di comunicazione è un sistema - un insieme di programmi, detto molto terra-terra - che consente a più computer collegati tra loro in qualche maniera di scambiarsi dei dati. Un esempio classico è Internet, un altro sono i computer collegati tra loro con schede di rete. I protocolli più usati sono NetBEUI, TCP/IP e IPX/SPX. Nel nostro caso, e in quello di Internet, adoperiamo TCP/IP.
Questo protocollo consente di condividere risorse in rete chiamando ogni computer con una serie di quattro numeri: l'indirizzo IP e l'indirizzo DNS. È anche possibile assegnare a questo numero un nome. Esempio: 194.243.65.1 è l'indirizzo del mio provider, ma se lo cerco come www.biella.alpcom.it lo trovo e ho il vantaggio di ricordarmelo più facilmente. In ogni computer è presente un name server che traduce il formato numerico in alfanumerico e viceversa.
Ad ogni indirizzo c'è la possibilità di usare più porte, per cui per usare la posta di Biella Multimedia, il mio provider, devo usare l'indirizzo 194.243.65.1 e la porta 25. Do tutto in pasto al mio programma e spedisco la mia lettera. Questo, in breve, è TCP/IP; rimando ogni discussione dettagliata a un'altra sede, in quanto la cosa è molto lunga e complessa.
Come si usa un socket con Java
Al contrario di com'era in C, scrivere un'applicazione in Java che comunichi via socket è alquanto semplice. Per prima cosa è necessario aprire questo socket creando un'istanza della classe Socket, poi si procede ad assegnare uno stream per l'output e uno per l'input, in maniera tale che sia possibile usare le funzioni println() e read(), come se si avesse a che fare con l'input/output da tastiera. Finito il tutto si devono, naturalmente, chiudere gli stream e il socket.
Vediamo un po' in dettaglio le varie classi utilizzate. La classe Socket è l'asse portante del programma. Tramite questa classe è possibile comunicare. I parametri da passare sono l'indirizzo, in formato alfanumerico, e la porta. Le altre classi sono molto utilizzate e conosciute e c'è poco da dire. PrintStream e InputStream, a cui si devono passare rispettivamente getOutputStream() e getInputStream(), sono quelle che permettono di usare il socket come se fosse uno stream locale.
Infatti, come si potrà vedere, stampare una stringa su schermo (System.out.println(Stringa)) o mandarla via socket (Sock.println(Stringa)) è praticamente la stessa cosa. Caso analogo è per l'input. È fondamentale, per evitare che il vostro provider vi linci per aver inchiodato una sua porta, chiudere il socket una volta terminato il programma, usando l'istruzione Sock.close().
Semplice applicativo per comunicazione tramite socket
Vediamo adesso con un esempio pratico come si possa trasmettere e ricevere una stringa tramite connessioni via socket.
Programma che spedisce
try {
Socket Sock = new Socket("biella.alpcom.it", 20000);
PrintStream os = new PrintStream(Sock.getOutputStream());
os.println("Heila!!");
os.close();
Sock.close();
} catch(Exception e) {
System.out.println(e);
}
Programma che riceve
try {
Socket Sock = new Socket("biella.alpcom.it", 20000);
InputStream is = Sock.getInputStream();
byte[] s = new byte[100];
is.read(s);
is.close();
Sock.close();
} catch(Exception e) {
System.out.println(e);
}
Come si può vedere, il programma si basa su quanto detto al paragrafo precedente e riceve o invia la stringa Heila!! attraverso la porta 20000 di biella.alpcom.it. Vi sconsiglio di usare questo provider per i vostri esperimenti, anche perché se ne accorgerebbe e non vi lascerebbe fare questo genere di cose.
Cenni sulla sicurezza dei dati
Come si è detto nella prima parte, i dati trasmessi via socket possono essere intercettati. E allora cosa si può fare per tenerli segreti? La risposta è semplice: basta criptarli. Visto che non vi è modo per evitare l'intercettazione, è sufficiente rendere illeggibili i dati, come fanno i militari con le loro comunicazioni, solo che in informatica la criptatura è molto più sicura.
Come si era accennato, tre sono i metodi fondamentali per proteggere i dati. Vediamo ora molto superficialmente quali sono e come funzionano. Il primo è quello classico. Si prende una parola chiave e si cripta il messaggio in base ad essa. Per decriptarlo occorre possedere la stessa parola chiave, altrimenti non se ne fa niente. È questo un metodo semplice da realizzare, ma di scarsa efficacia: infatti è relativamente semplice provare e, alla fine, trovare la parola chiave.
Il secondo metodo, ritenuto il più sicuro di tutti, si chiama PGP, che sta per Pretty Good Privacy, e si basa su due chiavi - una pubblica, da dare in giro, e una privata - e una frase segreta. Hanno calcolato che, per decriptare illegalmente un messaggio, una rete di 1000 computer dovrebbe lavorare per circa 10^10 anni, quindi mi sembra un metodo sicuro. Per maggiori informazioni, l'articolo rimandava al sito Geocities allora disponibile.
L'ultimo sistema è il più usato. Si chiama SSL, che sta per Secure Socket Layer, ed è lo stesso sistema usato per il protocollo HTTPS, le cosiddette pagine sicure che si usano per accettare numeri di carta di credito. Anche questo sistema si basa su due chiavi: una pubblica, con la quale criptare il messaggio, e una privata, con la quale decodificarlo. Esistono alcune routine, che per Java si chiamano SSLava, che permettono di usare in maniera quasi trasparente questo protocollo. Non è però questa la sede per parlarne, quindi rimando l'argomento al futuro.
Conclusioni
In questo articolo si è visto cosa sono i socket e come utilizzarli in propri applicativi scritti in Java. La teoria su TCP/IP, socket e tutto il resto è trasportabile su qualunque piattaforma e qualunque linguaggio, salvo per il fatto che Java offre, tra tutti, le maggiori facilitazioni. In seguito si potrà pensare di vedere nel dettaglio alcuni programmi che utilizzino i socket riservati, per esempio, alla posta (SMTP e POP).
