7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf ·...

49
Programmazione di Rete A.A. 2010/2011 Massimo Merro Universit` a degli Studi di Verona 7 Marzo 2011 Massimo Merro Univ. Verona Programmazione di Rete 1 / 247

Transcript of 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf ·...

Page 1: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Programmazione di Rete A.A. 2010/2011

Massimo Merro

Universita degli Studi di Verona

7 Marzo 2011

Massimo Merro Univ. Verona Programmazione di Rete 1 / 247

Page 2: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

I Socket

Nei sistemi distribuiti i dati vengono trasmessi sotto forma dipacchetti , di dimensione fissa.

Come visto nel corso di Reti, ogni pacchetto ha una struttura benprecisa: header + payload. L’header contiene, tra l’altro, gli indirizziIP di sender/receiver e le porte TCP/IP coinvolte. Il payload , invece,contiene i dati da trasmettere.

I pacchetti possono andare dispersi, essere daneggiati, oppure arrivarea destinazione disordinati. Percio la trasmissione di dati su reterichiede un lavoro di gestione dei pacchetti che viene astrattoattraverso strumenti opportuni.

I Socket sono l’astrazione attraverso cui due programmi in esecuzionesu macchine differenti possono scambiarsi dati sotto forma di flussi dibytes (streams) in input ed in output.

Massimo Merro Univ. Verona Programmazione di Rete 2 / 247

Page 3: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

I Socket fecero la loro prima comparsa a meta degli anni ’70 inambiente Unix. Nei successivi 40 anni, i socket sono divenuti unostrumento fondamentale della programmazione distribuita.

Un socket consente la connession tra due host: client e server.Le operazioni possibili lato server sono:

Creazione del socketBind ad una porta TCP/IPListen, predisposizione a ricevere dati in ingressoAccept, si accettano connessioni da parte di macchine remote sullaporta TCP/IPLettura/scrittura dei datiChiusura della connessione.

Mentre le operazioni possibili lato client sono:Creazione del socketConnect, richiesta di connessioneLettura/scrittura dei datiChiusura della connessione.

Massimo Merro Univ. Verona Programmazione di Rete 3 / 247

Page 4: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Il pacchetto java.net contiene due classi principali per lacomunicazione via socket: Socket e ServerSocket.

Socket abilita una singola comunicazione tra due processi. Per poterscambiare informazioni, entrambi i processi devono creare un’istanzadi Socket.

ServerSocket gestisce presso il server la fase iniziale dellaconnessione iniziale. Cosı, quando un client si connette ad un serverusando un’istanza di Socket, in realta comunichera con un’istanza diServerSocket presso il server. ServerSocket crea immediatamenteun’istanza di Socket e l’assegna al client. In un certo qual sensoSocket e simile ad una linea telefonica mentre ServerSocket esimile ad un centralino che crea manualmente una linea per consentirela comunicazione tra server e client.

Per creare una connessione di rete via socket con una macchinaremota sono necessarie due informazioni: l’indirizzo dell’host e ilnumero della porta TCP/IP usata dalla macchina remota.

Massimo Merro Univ. Verona Programmazione di Rete 4 / 247

Page 5: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

L’indirizzo di un host puo essere fornito o come un InetAddressoppure come un oggetto di tipo String.

La porta e una sorta di indirizzo relativo (cioe locale alla macchina)ed e rappresentato da un int strettamente positivo e minore o ugualedi 65535.

Massimo Merro Univ. Verona Programmazione di Rete 5 / 247

Page 6: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

I Sockets lato Client

La procedura attraverso cui un client Java usa un socket consiste inquattro passi:

Si crea un socket a partire dall’IP e dalla porta associata al serverremoto;

Il socket tenta di connettersi con il server remoto;

Una volta che la connessione e stabilita, l’host locale e quello remotoricavano i flussi in input (InputStream) ed output (Outputstream)associati al socket e si trasmettono le informazioni. L’InputStream eusato per ricevere dati mentre l’Outputstream serve per spedire dati;

Quando la trasmissione e terminata si chiude il socket. Quest’ultimopasso consente al server di disallocare le risorse allocate per lacomunicazione col client.

Massimo Merro Univ. Verona Programmazione di Rete 6 / 247

Page 7: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

La classe Socket ha vari costruttori. Vediamo il primo.

public Socket (String host, int port) throws UnknownHostException,IOException

Ad esempio:......try {

Socket tounivr = new Socket("www.univr.it", 80);// spedisci e ricevi dati

}catch (UnknownHostException ex){

System.err.println(ex);}catch (IOException ex){

System.err.println(ex);}

Massimo Merro Univ. Verona Programmazione di Rete 7 / 247

Page 8: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

In questo esempio l’host e espresso simbolicamente attraverso unoggetto di tipo String.

Se il DNS non riesce a risolvere il nome dell’host il costruttore lanciauna UnknownHostException

Se il socket non puo essere aperto per qualche altra ragione (server oconnessione non funzionante) allora viene lanciata una IOException.

Si noti che il costruttore non solo crea un oggetto di tipo Socket macerca anche di connettere il socket all’host remoto.

Cosı l’oggetto socket e anche utile per determinare se esiste un serverin ascolto su una determinata porta.

Massimo Merro Univ. Verona Programmazione di Rete 8 / 247

Page 9: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Nel seguente esempio si scandiscono le prime 1024 porte di un host allaricerca di un server in ascolto:

import java.net.*;import java.io.*;

public class LowPortScanner {public static void main (String[] args) {

String host = "localhost";if (args.length > 0) { host = args[0];}for (int i = 1; i < 1024; i++){

try {Socket s = new Socket(host, i);System.out.println("Esiste un server alla porta " + i + " di " + host);

}catch (UnknownHostException ex) {

System.err.println(ex);break;

}catch (IOException ex){ ....}

}}

}

Massimo Merro Univ. Verona Programmazione di Rete 9 / 247

Page 10: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Lanciando il codice LowPortScanner potremmo ottenere un’output deltipo:

Esiste un server alla porta 21 di localhostEsiste un server alla porta 22 di localhostEsiste un server alla porta 25 di localhostEsiste un server alla porta 139 di localhostEsiste un server alla porta 873 di localhost....................

Sebbene la LowPortScanner sia molto semplice, puo essere usata percapire cosa faccia la propria macchina e su quali porte, al fine dievitare possibili attacchi.

Puo servire anche per scovare usi impropri della vostra macchina,magari un server http su una porta non convenzionale che fornisceinformazioni “proibite”.

IMPORTANTE: non usate il precedente programma su una macchinache non sia di vostra esclusiva pertinenza. La maggior parte deisistemisti considerano l’esecuzione di programmi simili chescandiscono le porte come un attacco esterno.

Massimo Merro Univ. Verona Programmazione di Rete 10 / 247

Page 11: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Un altro costruttore della classe Socket e il seguente:

public Socket (InetAddress host, int port) throws UnknownHostException,IOException

L’esempio precedente diventa cosı:

......try {

InetAddress univr = InetAddress.getByName("www.univr.it");Socket tounivr = new Socket(univr, 80);// spedisci e ricevi dati

}catch (UnknownHostException ex){

System.err.println(ex);}catch (IOException ex){

System.err.println(ex);}

Massimo Merro Univ. Verona Programmazione di Rete 11 / 247

Page 12: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Un altro costruttore e il seguente:

public Socket (String host, int port, InetAddress interface, int localPort)throws UnknownHostException,

IOException

Questo costruttore crea un socket che tenta di connettersi all’host edalla porta specificati attraverso i primi due parametri.

La connessione avviene localmente utilizzando un’interfaccia locale direte ed una porta specificati negli ultimi due parametri.

L’interfaccia di rete puo essere fisica (ad esempio una differentescheda di rete) o virtuale (multihomed host).

Una situazione tipica in cui si sceglie esplicitamente l’indirizzo di retelocale potrebbe essere quella in cui si abbia un router/firewall che usaporte diverse per accessi diversi.

Esistono altre possibili combinazioni per i costruttori di Socket. Adesempio, esistono costruttori che consentono di creare un oggetto socketnon ancora connesso.

Massimo Merro Univ. Verona Programmazione di Rete 12 / 247

Page 13: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Ottenere informazioni da un socket

Vediamo alcuni metodi che ci consentono di ottenere informazioni relativiad un socket.

public InetAddress getInetAddress()Dato un socket ritorna l’InetAddress del remote host associato alsocket.

public int getPort()Fornisce la porta del remote host a cui il socket e connesso.

public int getLocalPort()Fornisce la porta locale della connessione socket.

public InetAddress getLocalAddress()Ritorna l’interfaccia di rete a cui il socket e connesso.

Vediamo un esempio in cui questi metodi vengono utilizzati:

Massimo Merro Univ. Verona Programmazione di Rete 13 / 247

Page 14: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

import java.net.*;import java.io.*;

public class SocketInfo {public static void main(String[] args) {

for (int i = 0; i < args.length; i++) {try {

Socket skt = new Socket(args[i], 80);System.out.println("Connesso a " + skt.getInetAddress()

+ " porta " + skt.getPort() "," + " dalla porta "+ skt.getLocalPort() + " di " skt.getLocalAddress());

}catch (UnknownHostException ex) {

System.err.println("Non trovo " + args[i]);}catch (SocketException ex) {

System.err.println("Non riesco a connettermi a " + args[i]);}catch (IOException ex) {

System.err.println(ex)}

}}

}

Massimo Merro Univ. Verona Programmazione di Rete 14 / 247

Page 15: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Cosı se invochiamo il precedente programma come segue:

java SocketInfo www.univr.it www.univr.it www.unipd.it login.ibiblio.org

Il risultato sara qualcosa del tipo:

Connesso a www.univr.it/157.27.6.235 porta 80, dalla porta 49156 di /157.27.10.252Connesso a www.univr.it/157.27.6.235 porta 80, dalla porta 49157 di /157.27.10.252Connesso a www.unipd.it/130.186.29.37 porta 80, dalla porta 49158 di /157.27.10.252Non riesco a connettermi a login.ibiblio.org

Si noti che “www.univr.it” e usato due volte come argomento permostrare che ad ogni connessione viene assegnata una diversa portalocale.

Tale porta non puo essere prevista in anticipo, ma dipende da qualiporte sono correntemente in uso.

La connessione a ”login.ibiblio.org” fallisce perche quella macchinanon ha in esecuzione alcun server alla porta 80.

Massimo Merro Univ. Verona Programmazione di Rete 15 / 247

Page 16: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Un’altro metodo della classe Socket e quello che consente di ricavarel’InputStream associato socket:

public InputStream getInputStream() throws IOException

In genere l’InputStream fornito da tale metodo viene agganciato aduno stream filtro che offra maggiori funzionalita, come ad esempioDataInputStream o InputStreamReader.

Per ragioni di efficienza, spesso si bufferizza l’input di uno streamutilizzando le classi BufferedInputStream o BufferedReader.

Utilizzando un input stream facciamo un piccolo esperimento con unprotocollo internet chiamato daytime. Il protocollo e molto semplice‘: ilclient apre un socket alla porta 13 del server che risponde fornendo ora edata in maniera leggibile.

Massimo Merro Univ. Verona Programmazione di Rete 16 / 247

Page 17: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

import java.net.*;import java.io.*;

public class DaytimeClient {public static void main(String[] args) {

String host;if (args.length > 0) { host = args[0];}else { host = "time.nist.gov";}try {

Socket skt new Socket(host, 13);InputStream timeStream = skt.getInputStream();StringBuffer time = new StringBuffer();int c;while ((c = timeStream.read()) != -1) time.append((char) c);String timeString = time.toString().trim();System.out.println("E’ " + timeString + " presso " + host);

}catch (UnknownHostException ex) {

System.err.println(ex);}catch (IOException ex) {

System.err.println(ex);}

}} Massimo Merro Univ. Verona Programmazione di Rete 17 / 247

Page 18: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

La DaytimeClient legge il nome di un datetime server da linea dicomando e crea una connessione socket con tale server alla porta 13.

Se il nome dell’host e omesso allora viene usato il server americanodella “National Institute of Standards and Technology”.

L’input stream del socket viene letto un carattere alla volta ememorizzato nella variabile time di tipo StingBuffer;

La stringa associata viene memorizzata nella variabile timeString evisualizzata.

Cosı ad esempio, a seguito dell’invocazione di

java DaytimeClient www.univr.it

il risultato potrebbe essere:

E’ Tue Mar 2 23:45:29 2010 presso www.univr.it

Massimo Merro Univ. Verona Programmazione di Rete 18 / 247

Page 19: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Il metodo della classe Socket che consente di ricavare l’OutputStreamassociato ad un socket e il seguente:

public OutputStream getOutputStream() throws IOException

Questo metodo consente di accedere all’output stream del socket perscriverci sopra dati da un programma. Similmente a quanto accade conl’InputStream, l’OutputStream puo essere convenientemente collegato astrem filtro come DataOutputStream e OutputStreamWriter.......Writer out;try {

Socket http = new Socket ("www.univr.it", 80);OutputStream raw = http.getOutputStream();OutputStream buffered = new BufferedOutputStream(raw);out = new OuputStreamWriter(buffered, "ASCII");out.write("GET / HTTP 1.0\r\n\r\n");// leggi le risposte del server

}finally {

try {out.close();

}catch (Exception ex) {....}

}Massimo Merro Univ. Verona Programmazione di Rete 19 / 247

Page 20: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Vediamo adesso un esempio in cui si utilizzano entrambi gli stream ininput e output.

Il protocollo echo e uno dei piu semplici protocolli TCP.

Il client apre un socket alla porta 7 sull’echo server e spedisce dei dati.

Il server, semplicemente, rispedisce indietro la medesima informazione.

Questo prootocollo puo essere utile per testare la rete e verificare chei dati non siano in qualche modo manipolati da router/firewall.

Nel prossimo lucido vediamo un esempio in cui si crea un socket versoil servizio di echo alla porta 7.

Massimo Merro Univ. Verona Programmazione di Rete 20 / 247

Page 21: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

import java.net.*;import java.io.*;

public class EchoClient {public static void main(String[] args) {

String host = ‘‘localhost’’;if (args.length > 0) {

host = args[0];}PrintWriter out = null;BufferedReader netIn = null;try {

Socket skt = new Socket(host, 7);netIn = new BufferedReader(new InputStreamReader(skt.getInputStream));BufferedReader userIn = new BufferedReader(new InputStreamReader(System.in));out = new PrinteWriter(skt.getOutputStream());System.out.println("Connesso all’echo server");while (true) {

String line = userIn.readLine();if (line.equals(".")) break;out.println(line);out.flush();System.out.println(netIn.readLine());

}}

Massimo Merro Univ. Verona Programmazione di Rete 21 / 247

Page 22: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

catch (IOException ex) {....}finally {

try {if (netIn != null) netIn.close();if (out != null) out.close();

}catch (IOException ex) {...}

}}

}

Utilizzando 2 classi filtro, l’input stream del socket e convogliato nella variabile netIn,attraverso cui si possono leggere le risposte del server.

Il programma legge righe dallo standard input attraverso la variabile userIn.Utilizzando una classe filto, l’output stream del socket e associato ad una variabile

chiamata out.Il programma funziona nel seguente modo:

Si legge l’input stream proveniente dallo standard input attraverso la variabile userIn e si

scrive l’informazione letta sull’output stream del socket out dell’echo server.

Si noti che l’utilizzo del metodo flush() per essere certi che l’informazione venga

effettivamente inviata al server.

Dopodiche si monitora l’input stream del socket (attraverso la variabile netIn) in attesa

di una risposta dell’echo server.

Quando su netIn si riceve un flusso, questo viene inviato allo standard output

System.out.

Massimo Merro Univ. Verona Programmazione di Rete 22 / 247

Page 23: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Cosı un esempio di esecuzione della EchoClient e la seguente:

% java EchoClient www.univr.it

Connesso all’echo server

Hello

Hello

How are you?

How are you?

I’m fine thank you!

I’m fine thank you!

Goodbye

Goodbye

.

Massimo Merro Univ. Verona Programmazione di Rete 23 / 247

Page 24: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Chiusura di un Socket

Vediamo adesso il metodo della classe Socket per chiudere un socket:

public void close() throws IOException

Fino adesso abbiamo assunto che i socket si chiudano da soli.

Questo e vero quando uno dei due stream associati al socket vienechiuso; quando il programma esce; oppure quando lo stream vienedisallocato dal garbage collector.

In generale, e comunque buona prassi chiudere un socket quando sitermina.

Anche perche in programmi che usano un alto numero di connessionisocket (come ad esempio un web broswer) il sistema puo facilmenteraggiungere il numero massimo di possibili socket aperti.

Cosı, quando si lavora con un socket bisognerebbe sempre invocare ilmetodo close().

Massimo Merro Univ. Verona Programmazione di Rete 24 / 247

Page 25: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Socket tounivr = null;try {

Socket tounivr = new Socket("www.univr.it", 80);// spedisci e ricevi dati

}catch (UnknownHostException ex){

System.err.println(ex);}catch (IOException ex){

System.err.println(ex);}finally {

if (tounivr != null) tounivr.close();}

Massimo Merro Univ. Verona Programmazione di Rete 25 / 247

Page 26: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Si noti che se un socket fallisce la connessione non necessita di esserechiuso; poiche non e stato mai aperto. Infatti quando unaconnessione fallisce la variabile del socket rimane a null.

Dopo la sua chiusura, le informazioni associate ad un socket come:l’InetAddress, la porta, la porta locale, l’indirizzo di rete sonoancora accessibili attraverso i metodi corrispondenti.

Comunque, se si tenta di ricavere l’InputStream o l’OutputStreamassociato ad un socket chiuso attraverso i metodi getInputStream()e getOutputStream() verra lanciata un eccezione IOException.

Massimo Merro Univ. Verona Programmazione di Rete 26 / 247

Page 27: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Altri metodi della classe Socket

public boolean isClosed()

Ritorna true se il socket e stato chiuso, false, altrimenti. Se il socketnon e stato mai connesso ritorna false.public boolean isConnected()

Il nome e un po’ fuorviante. Infatti ritorna true se il socket e statoconnesso ad un host remoto. Anche dopo che il socket e stato chiuso.Per determinare se un socket e correntemente aperto bisognautilizzare i due metodi precedenti come segue:

boolean connected = skt.isConnected() && ! skt.isClosed().Il metodo close() chiude entrambi i flussi in input e output delsocket. E comunque possibile chiudere solo una delle due connessioniattraverso i seguenti metodi:

public void shutdownInput() throws IOException

public void shutdonwOutput() throws IOException

Massimo Merro Univ. Verona Programmazione di Rete 27 / 247

Page 28: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Opzioni su sockets

public void setTcpNoDelay(boolean on) throws SocketException

Mettendo il parametro a true i pacchetti vegnono spediti il piuvelocemente possibile, indipendentemente dalla loro dimensione.public boolean getTcpNoDelay() throws SocketException

Testa se la modalita TCP-NODELAY e abilitata.public void setSoLinger (boolean on, int seconds) throws SocketException

Specifica cosa fare con i pacchetti che non sono stati ancora speditiquando il socket e chiuso. Se il parametro di linger e a zero alloraquando il socket viene chiuso i pacchetti rimanenti vengono scartati,altrimenti si tenta di spedire i pacchetti per un certo tempo espressoin secondi, prima di chiudere il socket.public int getTcpSoLinger() throws SocketException

Testa se la modalita TCP-SOLINGER e abilitata ed in caso positivoritorna il tempo di linger (-1 se e disabilitato).

Massimo Merro Univ. Verona Programmazione di Rete 28 / 247

Page 29: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

public void setSoTimeout(int milliseconds) throws SocketException

Un’invocazione read() su un InputStream associato ad un socket siblocca in attesa di poter leggere un byte. Con questo metodo si fissaun timeout, in millisecondi, passato il quale viene lanciata unaSocketTimeoutException. Il timeout deve essere strettamentepositivo. Un timeout uguale a zero viene interpretato come untimeout infinito.

public int getSoTimeout() throws SocketException

Ritorna il valore del timeout. Zero se il timeout e disabilitato.

public void setReceiveBufferSize(int size) throws SockeException,

IllegalArgumentException

public void setReceiveBufferSize(int size) throws SockeException,

IllegalArgumentException

Questi metodi consentono di variare la dimensione del buffer utlizzatoper ricevere e trasmettere informazioni. Un giusto dimensionamentodi tale buffer consente di migliorare le performance.

Massimo Merro Univ. Verona Programmazione di Rete 29 / 247

Page 30: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

public void setKeepAlive(boolean on) throws SocketException

Se settato positivamente, il client spedira occasionalmente unpacchetto (ogni due ore) per accertarsi che il server non sia crashato.Se il server non risponde a questo pacchetto entro 12 minuti il clientchiudera la connessione. Senza tale opzione un client inattivo puorestare connesso senza rendersi conto che il server e andato giu.

public boolean getKeepAlive() throws SocketException

Testa la modalita KEEP-ALIVE.

public void sendUrgentData(int data) throws IOException

Questa opzione permette di spedire un singolo byte di informazioneurgente. Questa informazione e spedita immeditatamente, sebbenedopo ogni altra scrittura fatta precedentemente.

Massimo Merro Univ. Verona Programmazione di Rete 30 / 247

Page 31: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Classi di servizio

Negli ultimi anni si e cercato di derivare differenti classi di servizio aseconda delle informazioni che si vogliono trasmettere.Ad esempio, trasmissioni video richiedono un alta banda, laddoveemail possono essere trasmesse usando una banda lenta.In alcuni sistemi, trasmissioni ad alta velocita hanno un prezzosuperiore per evitare che gli utenti ne abusino.Attualmente esistono 4 classi di servizio definite per dati TCP(sebbene non tutti i routers le supportano).Le classi sono le seguenti:

0x02: Low cost0x04: High reliability0x08: Maximum throughput0x10: Minimum delay

E possibile anche impostare una comunicazione combinando richieste.Ad esempio impostare una comunicazione low cost con il minimodelay possibile.

Massimo Merro Univ. Verona Programmazione di Rete 31 / 247

Page 32: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Queste classi sono gestite attraverso i due metodi:

public void setTrafficClass(int trafficClass) throw SocketException

Vediamo un esempio:Socket s new Socket("www.yahoo.com", 80);s.setTrafficClass(0x02);

Nel modo seguente si combinano modalita diverse, come ad esempiomaximum throughput e minimum delay.Socket s = new Socket("www.yahoo.com", 80);s.setTrafficClass(0x08 | 0x10);

Massimo Merro Univ. Verona Programmazione di Rete 32 / 247

Page 33: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

I Socket lato Server

Fino adesso abbiamo visto come utilizzare i socket lato client.

Vediamo adesso quali sono le operazioni necessarie per gestire isocket lato server.

A tal riguardo, Java fornisce la classe ServerSocket.

Un server socket sta in ascolto su una data porta della macchinaserver in attesa di conessioni da parte di un client.

Quando un client tenta di connettersi il server socket crea un oggettodi tipo Socket per la connessione con il client (dopo una brevenegoziazione).

Cosı, una volta che il server socket ha inizializzato la connessione, ilserver usa un oggetto di tipo Socket per spedire e ricevere datidall’ogetto Socket presso il client.

Massimo Merro Univ. Verona Programmazione di Rete 33 / 247

Page 34: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Vediamo brevemente il ciclo di vita di un server remoto in Java:

1 Si crea un oggetto di tipo ServerSocket e lo si mette in ascolto suuna porta TCP/IP.

2 Il server socket creato si mette in attesa di connessioni attraverso ilmetodo accept(). Tale metodo e bloccante, nel senso che il server siblocca fino a quando non si presenta un client, e solo allora vienecreato un oggetto Socket per la comunicazione col client.

3 A seconda della natura del server si ricava l’input stream e/o l’outputstream del socket per comunicare col client.

4 Server e client interagiscono in accordo con quanto specificato nelprotocollo del servizio.

5 Il server e/o il client chiudono la connessione.

6 Il server torna a mettersi in ascolto invocando il metodo accept().

Massimo Merro Univ. Verona Programmazione di Rete 34 / 247

Page 35: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Quando l’interazione client/server prende un tempo sufficientementelungo, la maggior parte dei server Unix creano un nuovo processo pergestire la singola connessione; in modo da poter gestire piu client allostesso tempo.

In Java, invece, il programmatore deve prendersi cura di lanciare laconnessione in un nuovo thread affinche il server possa accettarenuove richieste.

Ovviamente, l’uso dei threads e meno dispendioso, in termini di caricodi CPU, di quanto non sia la creazione di nuovi processi.

Il sistema operativo gestisce le connessioni in ingresso su una dataporta memorizzandole in attesa su una coda (politica FIFO).

La lunghezza di tale coda e tipicamente 50, sebbene possa variare daun sistema operativo ad un altro.

Una volta raggiunto il numero massimo di connessioni in attesa l’hostrifiuta ulteriori connessioni su quella porta.

Massimo Merro Univ. Verona Programmazione di Rete 35 / 247

Page 36: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Costruttori della classe ServerSocket

public ServerSocket(int port) throws BindException, IOException

public ServerSocket(int port, int queueLength) throws BindException, IOException

public ServerSocket(int port, int queueLength, InetAddress bindAddress) throws

BindException, IOException

E possibile specificare la porta su cui mettere in ascolto il serversocket; se si indica 0 il sistema scegliera una porta disponibile chechiameremo porta anonima.

E possibile specificare la lunghezza della coda delle connessioni iningresso in attesa di essere servite.

E possibile anche specificare l’interfaccia di rete locale che si intendeutilizzare. Ad esempio, se si vuole utilizzare un indirizzo IP locale nonvisibile dall’esterno.

Esistono construttori che consentono di creare un serversocket nonconnnesso.

Massimo Merro Univ. Verona Programmazione di Rete 36 / 247

Page 37: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Vediamo come creare un server socket da utilizzare per un server httppotremmo scrivere:

try {ServerSocket http = new ServerSocket(80);

}catch (IOException ex) {

System.err.println(ex);}

Il costruttore lancia un’eccezione IOException (e precisamente unaBindException) se il socket non puo essere creato e legato allaporta indicata.

La comparsa di una IOException quando si crea un oggetto di tipoServerSocket e quasi sempre dovuta a una delle due seguentiragioni:

Un altro server socket (possibilmente associato ad un server differente)sta gia usando la porta;si sta cercando di utilizzare una porta di sistema, da 1 a 1024, senza iprivilegi adeguati (superuser).

Massimo Merro Univ. Verona Programmazione di Rete 37 / 247

Page 38: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Usiamo il costruttore di ServerSocket per scrivere un programma similealla PortScanner vista precedentemente:

import java.net.*;import java.io.*;

public class LocalPortScanner {public static void main(String[] args) {

for (int port = 1; port <= 65535; port++) {try {

// the next line will fail and drop into the catch block if// there is already a server running on the portServerSocket server = new ServerSocket(port);

}catch (IOException ex) {

System.out.println("There is a server on port " + port + ".");} // end catch

} // end for}

}

Massimo Merro Univ. Verona Programmazione di Rete 38 / 247

Page 39: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Cosı l’esecuzione di tale programma potrebbe dare il seguente output:

java LocalPortScanner

There is a server on port 135.

There is a server on port 1025.

There is a server on port 1026.

There is a server on port 1027.

There is a server on port 1028.

Massimo Merro Univ. Verona Programmazione di Rete 39 / 247

Page 40: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Accettare e chiudere connessioni

Un server socket normalmente opera in loop in cui si accettanoconnessioni da client diversi, attraverso l’invocazione del metodoaccept().

Quando la transazione e terminata il server dovrebbe invocare ilmetodo close() del socket.

Se il client chiude la connessione mentre il server sta ancora operando,quest’ultimo andra incontro ad una InterruptedIOException.

Ricordiamo che il metodo accept() sospende l’esecuzione del serverfino a quando non si presenta un client.

Solo allora viene creato un oggetto di tipo Socket da cui e possibilericavare l’input stream e output stream attraverso i metodigetInputStream() e getOutputStream(), rispettivamente.

Massimo Merro Univ. Verona Programmazione di Rete 40 / 247

Page 41: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Vediamo un esempio:

.......ServerSocket server = new ServerSocket(5776);while (true) {

Socket connection = server.accept( );OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream( ));out.write("You’ve connected to this server. Bye-bye now.\r\n");connection.close( );

}

Se non si vuole che il programma si blocchi in attesa di unaconnessione bisognera porre l’invocazione del metodo accept() in unthread a parte.

Quando si catturano le eccezioni e importante distinguere traeccezioni che devono causare la chiusura del server ed eccezioni cheinvece devono solo comportare la chiusura della connessione.

Eccezioni causate dall’esecuzione del metodo accept() nondovrebbero causare lo shut down del server.

Massimo Merro Univ. Verona Programmazione di Rete 41 / 247

Page 42: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Sebbene certi protocolli possano specificare che i socket siano chiusidai client, e buona norma che se ne occupi il server.Si noti che eventuali IOException durante la chiusura di un socketpossono essere dovuti al fatto che il client ha gia chiuso il socket.

try {ServerSocket server = new ServerSocket(5776);while (true) {

Socket connection = server.accept( );try {

Writer out = new OutputStreamWriter(connection.getOutputStream());out.write("You’ve connected to this server. Bye-bye now.\r\n");out.flush();connection.close();

}catch (IOException ex) {

// This tends to be a transitory error for this one connection;// e.g. the client broke the connection early.

}finally {

try {if (connection != null) connection.close( );

}catch (IOException ex) {}

}}catch (IOException ex) {

System.err.println(ex);}

Massimo Merro Univ. Verona Programmazione di Rete 42 / 247

Page 43: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Di seguito mostreremo un semplice server daytime.Tale server spedisce una singola linea di testo (contenente l’ora) aseguito di una invocazione, che viene quindi servita immediatamente.Server piu complessi dovrebbero usare i threads per gestire piurichieste. In questo caso, il rallentamento dovuto all’uso dei threadsarebbe superiore al tempo necessario per servire la richiesta.

import java.net.*;import java.io.*;import java.util.Date;

public class DaytimeServer {public final static int DEFAULT_PORT = 13;public static void main(String[] args) {int port = DEFAULT_PORT;if (args.length > 0) {

try {port = Integer.parseInt(args[0]);if (port < 0 || port >= 65536) {

System.out.println("Port must between 0 and 65535");return;

}}

....Massimo Merro Univ. Verona Programmazione di Rete 43 / 247

Page 44: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

catch (NumberFormatException ex) { // use default port }}try {

ServerSocket server = new ServerSocket(port);Socket connection = null;while (true) {

try {connection = server.accept();Writer out = new OutputStreamWriter(connection.getOutputStream( ));Date now = new Date( );out.write(now.toString() +"\r\n");out.flush();connection.close();

}catch (IOException ex) {}finally {

try { if (connection != null) connection.close( );}catch (IOException ex) {}

}} // end while

} // end trycatch (IOException ex) { System.err.println(ex);} // end catch

} // end main} // end DaytimeServer

Massimo Merro Univ. Verona Programmazione di Rete 44 / 247

Page 45: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Chiusura di ServerSocket

Quando si termina con un server socket, sara cura del server dichiudere tale socket, al fine di liberare la porta associata.

Alla chiusura di un server socket, vegnono automaticamente chiusitutti gli oggetti Socket che il server ha “accettato”.

Vediamo un semplice esempio:

for (int port = 1; port <= 65535; port++) {try {

// the next line will fail and drop into the catch block if// there is already a server running on the portServerSocket server = new ServerSocket(port);server.close( );

}catch (IOException ex) {

System.out.println("There is a server on port " + port + ".");}

} // end for

Massimo Merro Univ. Verona Programmazione di Rete 45 / 247

Page 46: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

I metodi get

Similmente a quanto visto per Socket esistono i seguenti metodi:public InetAddress getInetAddress()

Dato un ServerSocket ritorna l’InetAddress associato al socket.public int getLocalPort()

Fornisce la porta a cui il ServerSocket e connesso. Quest’ultimometodo e utile quando si usano porte anonime:

import java.net.*;import java.io.*;

public class RandomPort {public static void main(String[] args) {

try {ServerSocket server = new ServerSocket(0);System.out.println("This server runs on port " + server.getLocalPort( ));

}catch (IOException ex) {

System.err.println(ex);}

}} Massimo Merro Univ. Verona Programmazione di Rete 46 / 247

Page 47: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Esistono inoltre i seguenti metodi per verificare la chiusura/apertura di unServerSocket.

public boolean isClosed()

Ritorna true se il socket e stato chiuso, false, altrimenti. Se il socketnon e stato mai connesso ritorna false.

public boolean isConnected()

Il nome e un po’ fuorviante. Infatti ritorna true se il socket e statoconnesso ad un host remoto. Anche dopo che il socket e stato chiuso.

Per determinare se un socket e correntemente aperto bisognautilizzare i due metodi precedenti come segue:

public static boolean isOpen(ServerSocket ss) {return ss.isConnected() && ! ss.isClosed()};

}

Massimo Merro Univ. Verona Programmazione di Rete 47 / 247

Page 48: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Lanciando tale programma potremmo ottenere il seguente output:

java RandomPort

This server runs on port 1154

java RandomPort

This server runs on port 1155

java RandomPort

This server runs on port 1156

Come si puo notare, almeno in questa VM, le porte non sono veramenterandom ma sono determinate in sequenza rispetto ad una porta scelta aruntime.

Massimo Merro Univ. Verona Programmazione di Rete 48 / 247

Page 49: 7 Marzo 2011 - profs.scienze.univr.itprofs.scienze.univr.it/~merro/files/socket.pdf · L’indirizzo di un host puo essere fornito o come un InetAddress oppure come un oggetto di

Il metodo toString()

public String toString()

invocato su un oggetto ServerSocket ritornera una stringa col seguenteformato:

ServerSocket[addr=0.0.0.0,port=0,localport=5776]

Dove:

addr e l’indirizzo dell’interfaccia di rete locale a cui e legato ilServerSocket. Tale indirizzo sara 0.0.0.0 se il ServerSocket e legato atutte le interfacce, come nella maggior parte dei casi.

Il campo port assume sempre valore 0.

il campo localport ritorna la porta locale su cui il server e in attesadi connessioni.

Massimo Merro Univ. Verona Programmazione di Rete 49 / 247