Socket programming in Java
La realizzazione di un server in Java consente di scrivere
una sola versione eseguibile su diverse piattaforme.
Il linguaggio dispone del package java.net per la
gestione della comunicazione di rete.
Principali classi del package java.net
Classe
Cosa rappresenta?
Classi
derivate
InetAddress
un indirizzo IP (v4 o v6) o un nome di
dominio (risolto in modo trasparente via
DNS)
Inet4Address
Inet6Address
Socket
il socket client di una connessione TCP
SSLSocket
ServerSocket
il socket di ascolto di un server TCP
SSLServerSocket
DatagramSocket
il socket che usa il protocollo UDP
DatagramPacket
un pacchetto UDP (meglio: datagramma) da
trasmettere o ricevere. Comprende indirizzo
IP e porta (mittente o destinatario)
URL
una qualsiasi risorsa sul web mediante il
suo Uniform Resource Locator
Principali eccezioni sollevate da classi del package java.net
Eccezione
Cosa rappresenta?
SocketException
Errore di comunicazione
MalformedURLException
Errore nel formato di un URL
ProtocolException
Errore nel protocollo di trasporto
utilizzato (TCP o UDP)
SocketTimeoutException
Superamento attesa massima per una
lettura o una connessione
UnknownHostException
Errore di risoluzione del nome di un
host in indirizzo IP
Eccezioni
derivate
ConnectException
NoRouteToHostException
PortUnreachableException
Socket UDP in Java
La classe del package java.net che permette di gestire trasmissione
e ricezione di datagrammi UDP è: DatagramSocket
Metodi principali della classe DatagramSocket
DatagramSocket
Costruttore. Permette di specificare un dato numero di porta per il socket
setSoTimeout
Imposta tempo massimo di attesa di un datagramma per il metodo receive
setBroadcast
Abilita / disabilita possibilità di ricevere o trasmettere in modalità broadcast
receive
Riceve un datagramma UDP
send
Tramette un datagramma UDP
close
Chiude il socket
Datagrammi UDP : DatagramPacket
I datagrammi UDP sono rappresentati da oggetti della classe DatagramPacket
Metodi principali della classe DatagramPacket
DatagramPacket
Costruttore. Permette di specificare il contenuto del datagramma, la dimensione in
byte. In caso di invio, l'indirizzo IP e la porta di destinazione
setAddress
getAddress
Imposta / acquisisce l'IP associato al datagramma
setData
getData
Imposta / acquisisce i dati del datagramma (un array di byte)
setLength
getLength
Imposta / acquisisce la dimensione in byte dei dati del datagramma
setPort
getPort
Imposta / acquisisce il numero dio porta
Indirizzi IP : InetAddress
Per rappresentare l'indirizzo IP (versione 4 o 6) di un host / server si utilizza la
classe InetAddress
Metodi principali della classe InetAddress
getByAddress
Metodo statico. Data la rappresentazione binaria di un indirizzo restituisce un
oggetto di classe InetAddress
getByName
Metodo statico. Dato il nome di dominio di un host (o la rappresentazione di un IP in
forma testuale) restituisce un oggetto di classe InetAddress
getLocalHost
Metodo statico, senza parametri. Restituisce un oggetto di classe InetAddress
che rappresenta l'indirizzo IP del computer su cui viene eseguito il metodo
getAddress
Dato un oggetto InetAddress, restituisce la rappresentazione binaria dell'indirizzo
rappresentato dall'oggetto
getHostName
Dato un oggetto InetAddress, restituisce il nome di dominio (o la
rappresentazione testuale dell'indirizzo IP)
getHostAddress
Dato un oggetto InetAddress, restituisce la rappresentazione testuale
dell'indirizzo IP rappresentato dall'oggetto
isReachable
Dato un oggetto InetAddress, restituisce un valore booleano che indica se
l'indirizzo è raggiungibile o meno
Nota: la classe è priva di costruttori
Server e Client TCP in Java
1. Un Server TCP crea un oggetto di classe ServerSocket usato come socket
di ascolto delle richieste dei client
2. L'ascolto è effettuato mediante il metodo accept invocato sull'oggetto
ServerSocket. Il metodo mette il programma in attesa di richieste di
connessione.
3. All'arrivo di una richiesta il metodo restituisce un oggetto di classe Socket.
Tale oggetto rappresenta il socket su cui avverrà la comunicazione connection
oriented con il client.
4. Il Client si connette al server creando un oggetto di classe Socket,
specificando come parametri indirizzo IP e porta del Server.
5. Client e server inviano / ricevono dati usando le operazioni di lettura e scrittura
sul flusso (stream) di dati associati al socket di comunicazione
6. Al termine della comunicazione, Server e Client chiudono il socket di
comunicazione
IMPORTANTE: Se si vuole avere un server che possa gestire più comunicazioni contemporanee con
diversi Client (server concorrente), è necessario che al punto 3 il Server crei un thread a cui passerà
come parametro il socket di comunicazione. In questo modo il Server potrà subito rimettersi in ascolto di
nuove richieste mentre il thread porterà avanti la comunicazione col Client.
Server TCP: concorrente o iterativo?
Server iterativo
Server concorrente
1. Il server istanzia un socket di ascolto (oggetto
ServerSocket) e ...
2. ... si mette in attesa di richieste con accept
3. All'arrivo di una richiesta il server avvia la
comunicazione sul socket (oggetto Socket)
restituito da accept
4. Al termine della comunicazione ritorna al punto 2
1. Il server istanzia un socket di ascolto (oggetto
ServerSocket) e ...
2. ...si mette in attesa di richieste con accept
3. All'arrivo di una richiesta il server crea un nuovo
thread, a cui passa come parametro il socket
(oggetto Socket) restituito da accept. Il thread
si occuperà di gestire la comunicazione col client
4. Dopo aver avviato il thread di gestione della
comunicazione, il server ritorna subito al punto 2
-
Se la comunicazione (punto 3) si protrae,
eventuali nuove richieste restano in sospeso
Eventuali richieste di nuove connessioni da altri
client che arrivano durante la fase 3 non possono
essere servite: verranno messe in attesa finché
la comunicazione in corso non termina.
- La creazione e l'avvio di un thread avvengono
quasi istantaneamente e il server può rimettersi
subito in ascolto di nuove richieste, mentre il
thread porta avanti la comunicazione col client
- Eventuali richieste di nuove connessioni da altri
client possono essere servite immediatamente.
Il server può gestire un solo client per volta
È accettabile solo nel caso di semplici servizi
(es.: time server) in cui il client si connette, riceve
una breve informazione e chiude subito la
comunicazione.
• Il server può gestire più client in contemporanea,
creando un thread per ciascun client
• È adatto nel caso di servizi in cui la
comunicazione client-server può protrarsi per più
tempo.
-
•
•
Server TCP iterativo: esempio
Socket di ascolto richieste TCP in Java
La classe che permette di creare un socket per un server TCP è
ServerSocket. Essa rappresenta il socket di servizio su cui il server
TCP riceverà le richieste di connessione dei Client.
Metodi principali della classe ServerSocket
ServerSocket
Costruttore. Permette di specificare un dato numero di porta TCP e opzionalmente il
numero massimo di client in attesa di connessione.
setSoTimeout
Imposta tempo massimo di attesa per una richiesta di connessione. Se non arriva
nessuna richiesta entro il timeout stabilito viene lanciata un'eccezione di tipo
SocketTimeoutException.
accept
Attende una richiesta di connessione da parte di un client. Restituisce un oggetto
Socket, che rappresenta il socket su cui avverrà la comunicazione vera e propria
col client.
close
Chiude il socket di ascolto.
Socket per la comunicazione TCP in Java: classe Socket
La comunicazione TCP tra Client e Server avviene utilizzando un oggetto di classe Socket. Sul lato server, tale
oggetto è restituito dal metodo accept della classe ServerSocket, al momento in cui arriva la richiesta dal Client.
Metodi principali della classe Socket
Socket
Costruttore. Può avere come parametri indirizzo IP e porta a cui connettersi. Se senza parametri,
crea un socket non ancora connesso, su cui si potrà invocare successivamente il metodo
connect.
connect
Consente a un client di connettersi al server. Accetta come parametro un oggetto
InetSocketAddress che rappresenta IP e porta del server. Permette di specificare
opzionalmente un timeout per l'attesa.
isConnected
Restituisce un boolean che indica lo stato di connessione
getInetAddress
Restituisce l'indirizzo IP a cui il socket è connesso
getPort
Restituisce il numero di porta remota TCP
getOutputStream
Restituisce l'oggetto stream su cui inviare dati
getInputStream
Restituisce l'oggetto stream su cui ricevere dati
shutdownInput
Disabilita lo stream di input
shutdownOutput
Disabilita lo stream di output
setSoTimeout
Imposta un timeout (in msec) per la ricezione di dati. Superato il timeout viene lanciata
un'eccezione di tipo SocketTimeoutException
close
Chiude il socket e disconnette
Flussi di input / output su socket
InputStream e OutputStream
I metodi getInputStream e getOutputSream di oggetti Socket forniscono
gli stream di tipo InputStream e OutputStream su cui ricevere / inviare dati.
Metodi principali della classe InputStream
available
Restituisce il numero di byte ricevuti e non ancora letti
read
Legge un array di byte e restituisce il numero di byte letti (-1 se lo steam è
terminato)
close
Chiude lo stream di lettura
Metodi principali della classe OutputStream
flush
Svuota lo stream di output e forza la scrittura dei byte ancora bufferizzati
write
Scrive un array di byte sullo stream
close
Chiude lo stream di scrittura
Indirizzo di trasporto completo : InetSocketAddress
Per rappresentare l'indirizzo completo di un socket si usa la classe InetSocketAddress. Un
oggetto di tale classe può essere passato come parametro al metodo connect di un oggetto
Socket.
Metodi principali della classe InetSocketAddress
InetSocketAddress
Costruttore. Permette di specificare l'indirizzo IP o il nome del server (risolto via
DNS) e il numero di porta.
getAddress
Restituisce l'indirizzo IP del socket address come oggetto di tipo InetAddress
getPort
Restituisce il numero di porta del socket address
isUnresolved
Verifica se il nome del server è stato risolto via DNS