Come gestire Java SocketException

1. Introduzione

In questo breve tutorial, impareremo le cause di SocketException con un esempio.

Ovviamente discuteremo anche di come gestire l'eccezione.

2. Cause di SocketException

La causa più comune di SocketException è la scrittura o la lettura di dati in o da una connessione socket chiusa. Un'altra causa è la chiusura della connessione prima di leggere tutti i dati nel buffer del socket.

Diamo uno sguardo più da vicino ad alcuni motivi comuni sottostanti.

2.1. Rete lenta

Una cattiva connessione di rete potrebbe essere il problema sottostante. L'impostazione di un timeout di connessione socket più elevato può ridurre la frequenza di SocketException per le connessioni lente:

socket.setSoTimeout(30000); // timeout set to 30,000 ms

2.2. Intervento firewall

Un firewall di rete può chiudere le connessioni socket. Se abbiamo accesso al firewall, possiamo spegnerlo e vedere se risolve il problema.

Altrimenti, possiamo utilizzare uno strumento di monitoraggio della rete come Wireshark per controllare le attività del firewall.

2.3. Connessione inattiva lunga

Le connessioni inattive potrebbero essere dimenticate dall'altra parte (per risparmiare risorse). Se dobbiamo utilizzare una connessione per un lungo periodo, possiamo inviare messaggi heartbeat per prevenire lo stato di inattività.

2.4. Errore dell'applicazione

Ultimo ma non meno importante, SocketException può verificarsi a causa di errori o bug nel nostro codice.

Per dimostrarlo, avviamo un server sulla porta 6699:

SocketServer server = new SocketServer(); server.start(6699);

Quando il server viene avviato, aspetteremo un messaggio dal client:

serverSocket = new ServerSocket(port); clientSocket = serverSocket.accept(); out = new PrintWriter(clientSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String msg = in.readLine();

Una volta ottenuto, risponderemo e chiuderemo la connessione:

out.println("hi"); in.close(); out.close(); clientSocket.close(); serverSocket.close();

Quindi, supponiamo che un client si connetta al nostro server e invii "ciao":

SocketClient client = new SocketClient(); client.startConnection("127.0.0.1", 6699); client.sendMessage("hi");

Fin qui tutto bene.

Tuttavia, se il client invia un altro messaggio:

client.sendMessage("hi again");

Poiché il client invia di nuovo "ciao" al server dopo che la connessione è stata interrotta, si verifica una SocketException .

3. Gestione di una SocketException

La gestione di SocketException è piuttosto semplice e diretta. Simile a qualsiasi altra eccezione verificata, dobbiamo lanciarla o circondarla con un blocco try-catch.

Gestiamo l'eccezione nel nostro esempio:

try { client.sendMessage("hi"); client.sendMessage("hi again"); } catch (SocketException e) { client.stopConnection(); }

Qui, abbiamo chiuso la connessione client doposi è verificata l'eccezione. Il nuovo tentativo non funzionerà perché la connessione è già chiusa. Dovremmo invece avviare una nuova connessione:

client.startConnection("127.0.0.1", 6699); client.sendMessage("hi again");

4. Conclusione

In questo articolo, abbiamo esaminato le cause di SocketException e come gestirlo.

Come sempre, il codice è disponibile su Github.