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