# Java/Socket

* Java
* Linguaggio Java
* categoria · sviluppo ·
* Come posso contribuire?
* → Vai su Wikiversity
* Guida alla programmazioneJava/Introduzione - Specifica di linguaggioJava/Tipi di dato - Libreria standard
* Comunicazione serialeJava/Comunicazione seriale
* Stream
* Input e output su consoleJava/Input e output
* Java Collections Framework
* AWT e SwingJava/AWT e Swing
* Reflection
* SerializzazioneJava/Serializzazione
* SocketJava/Socket
L'accesso ai socket nel in Java avviene tramite l'uso delle classi e delle interfacce presenti nel package java.net. Un'applicazione può, quindi, accedere a flussi di dati su reti basate sui protocolli TCP/IP e UDP/IP.
Si utilizzano in particolare le seguenti classi:
* InetAddress, per la gestione degli indirizzi IP
* ServerSocket, per la creazione di socket lato server
* Socket, per la creazione di socket lato client
* DatagramSocket, implementa i socket per la trasmissione senza connessione
* MulticastSocket, fornisce supporto per i socket di tipo multicast

## Indirizzo IP

In Java un indirizzo IP è rappresentato dalla classe InetAddress: questa fornisce tutti quei metodi necessari a manipolare un indirizzo internet, necessario all'instradamento dei dati sulla rete. In particolare:
* getAllByName(String host) - è un metodo che ritorna tutti gli indirizzi internet di un host dato il suo nome in forma estesa (esempio: getAllByName("www.wikipedia.org"))
* getByName(String host) - ritorna un oggetto INetAddress che rappresenta l'indirizzo IP dell'host.
* getHostName ritorna una stringa rappresentante il nome dell'host.

## Socket Lato Server

Per realizzare un canale di comunicazione Client/Server occorre la creazione di un programma Server che rimane in ascolto su una determinata porta, e di un programma Client che, da remoto, lo invochi.
Per la creazione del programma Server in Java è necessario seguire i seguenti passaggi:
* Importare i package java.io e java.net per poter utilizzare le classi Socket e ServerSocket
* Intercettare l'eccezione IOException che deve essere gestita (tramite try e catch) o propagata (tramite throws), dato che vengono richiamati metodi delle classi che appartengono ai package java.io e java.net.
* Creare un oggetto ServerSocket, utilizzando il costruttore ServerSocket(int port) che si aspetta come parametro la porta del Server in ascolto per il servizio da attivare. Ad esempio:
Da notare che il numero corrispondente alla porta di ascolto non è una stringa.
* Utilizzare il metodo accept dell'oggetto ServerSocket per poter accettare le chiamate Client su un oggetto Socket:
Il metodo che viene invocato ritorna un oggetto Socket che potrà essere utilizzato per le comunicazioni con il client
* Creare due oggetti InputStreamReader e DataOutputStream per attivare uno stream di comunicazione con il cliente (ovviamente l'InputStreamReader servirà per leggere le richieste del client, e il DataOutputStream per inviare risposte al client):
* Richiamare il metodo close sugli oggetti dello stream e sull'oggetto ServerSocket per chiudere i canali di comunicazione:
Per avere informazioni sul server in ascolto, Java mette a disposizione la classe InetAddress ed i metodi getInetAddress e getLocalPort per identificare, rispettivamente, il nome del server e la porta impiegata. Il metodo getInetAddress della classe ServerSocket permette di ottenere un dato che deve essere analizzato dalla classe InetAddress per poterne ricavare un valore stringa comprensibile. Dunque per conoscere l'indirizzo del server bisogna effettuare
Per quanto riguarda il numero della porta utilizzato per ascoltare le chiamate client, bisogna utilizzare il metodo getLocalPort della classe ServerSocket in questo modo
A livello implementativo, un programma Server deve contenere, dopo una inizializzazione, un ciclo, possibilmente infinito o condizionato da uscita del programma, in cui viene atteso in maniera sincrona il collegamento del client: ad ogni iterazione verrà creato un oggetto Socket che permetterà di stabilire tale collegamento e gestirà il flusso di dati, ricavabili tramite la DataInputStream.
Un esempio di programmazione del server è:

## Socket Lato Client

A livello client i passaggi sono i seguenti:
* Importare i package java.io, java.net per utilizzare le classi Stream (per i canali di comunicazione) e Socket (per il nostro scopo)
* Intercettare l'eccezione IOException che deve essere gestita (tramite try e catch) o propagata (tramite throws), dato che vengono richiamati metodi delle classi che appartengono ai package java.io e java.net.
* Creare un oggetto Socket e specificare l'indirizzo IP ed il numero di porta in ascolto sul server, caratteristiche imposte dal TCP per la comunicazione server/client. Ad esempio, per connettersi al server descritto negli esempi sopra, si deve effettuare un'inizializzazione nel seguente modo:
A livello client l'indirizzo IP viene ricavato mentre la porta viene assegnata in modo dinamico in base alla disponibilità.
* Creare il canale di comunicazione con il server per inviare e ricevere messaggi tramite gli Stream di Byte in input ed output tramite le classi DataInputStream e DataOutputStream, associandole ai metodi getInputStream e getOutputStream della classe Socket.
* Chiudere gli stream di comunicazione e l'oggetto socket

## Server Multithreading

Nella pratica succede spesso che un server deve poter gestire le richieste di più client (come ad esempio nella richiesta di una pagina web da parte di più browser). Per fare questo è necessario attivare un thread separato per ogni richiesta: si deve pertanto sfruttare la programmazione multithreading messa a disposizione dal Java, effettuando un'estensione della classe Thread (o, alternativamente, un'implementazione dell'interfaccia Runnable).
Quello che segue è un esempio di server multithread. Sostanzialmente la tecnica è quella di creare un oggetto che funga da server, e tante sessioni, in thread separati, quante chiamate vengono effettuate dai client.
* Per prima cosa si importano le librerie java.io e java.net
* la classe che gestisce il server sarà un'estensione della classe Thread
* vengono dichiarate alcune variabili all'interno della classe che verranno utilizzate in seguito
* Il costruttore della classe ha come oggetto il socket del client che effettua la richiesta di connessione al server. Inoltre in questa fase ci si occupa di aprire il canale di comunicazione e di far partire il thread associato alla gestione del servizio
* Metodo che permette la gestione del servizio, verrà chiamata a seguito di this.start dell'oggetto serverMT:

## Note

* ↑ Javadoc della classe INetAddress, su download.oracle.com. URL consultato il 5 giugno 2011.