Java Socket: chiacchierate tra computer

Se sei arrivato in quinta probabilmente hai già sentito parlare di socket, client-server, TCP, UDP e tutto il teatrino della comunicazione di rete. Ma tra sentirne parlare e metterci davvero le mani in Java… c’è di mezzo il mare (o, meglio, un paio di porte e un bel po’ di byte).

In questo articolo ti porto a fare un giro veloce ma completo nel fantastico mondo dei Java Socket: come funzionano, quando usare TCP o UDP, cosa vuol dire server multiplo e multicast e — bonus — come c’entra Winsock in tutta questa storia.

Client-Server: due che si parlano (e uno che ascolta)

Il modello client-server è in pratica una telefonata: uno parla (client), l’altro ascolta (server).
Il server apre una porta (per esempio la 8080) e resta in attesa di connessioni.
Il client prova a collegarsi a quella porta e, se qualcuno risponde, cominciano a scambiarsi dati.

In Java, questa magia si realizza con due classi chiave:

  • ServerSocket → lato server
  • Socket → lato client (e lato server una volta accettata una connessione)

TCP e UDP: due modi diversi di mandare pacchetti

TCP (Transmission Control Protocol)

È come spedire un pacco con ricevuta di ritorno:

  • affidabile
  • ordinato
  • ritrasmette se qualcosa va storto

Uso tipico: web, file transfer, chat, applicazioni che non possono perdere dati.
In Java si usa Socket e ServerSocket.

UDP (User Datagram Protocol)

È come lanciare un frisbee: veloce, leggero, ma potrebbe cadere.

  • nessuna garanzia di consegna
  • niente connessione stabile
  • super rapido

Uso tipico: streaming, giochi online, comunicazioni in tempo reale.
In Java si usa DatagramSocket e DatagramPacket.

Server multiplo: quando un solo server non basta

Un server multiplo è un server che accetta più client contemporaneamente.
Java non fa magie: il trucco è usare thread multipli (o thread pool).
Il ServerSocket resta in ascolto, ogni volta che un client si connette si crea un nuovo Socket, e quel socket viene gestito da un thread dedicato.

Senza questo meccanismo, il server risponderebbe a un solo client alla volta… e la rete sarebbe praticamente inutile.

Multicast: parlare a molti senza chiamarli uno per uno

Con UDP multicast, un solo mittente può spedire lo stesso pacchetto a un gruppo di destinatari.
È come una radio: trasmetti una volta, tutti ascoltano.

In Java, multicast funziona con:

  • MulticastSocket
  • indirizzi speciali (classe D: da 224.0.0.0 a 239.255.255.255)

Ideale per:

  • streaming
  • discovery di servizi
  • aggiornamenti broadcast

TCP in Java: esempio mini di client e server

Server TCP basic

ServerSocket server = new ServerSocket(5000);
System.out.println("In ascolto sulla porta 5000...");

Socket client = server.accept();
System.out.println("Client connesso!");

BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true);

out.println("Benvenuto!");
System.out.println("Client dice: " + in.readLine());

client.close();
server.close();

Client TCP basic

Socket socket = new Socket("localhost", 5000);

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

System.out.println("Server dice: " + in.readLine());
out.println("Ciao server!");

socket.close();

UDP in Java: veloce e leggero

Server UDP

DatagramSocket socket = new DatagramSocket(5000);
byte[] buffer = new byte[1024];

DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);

String msg = new String(packet.getData(), 0, packet.getLength());
System.out.println("Ricevuto: " + msg);

socket.close();

Client UDP

DatagramSocket socket = new DatagramSocket();
byte[] data = "Ciao server!".getBytes();

InetAddress address = InetAddress.getByName("localhost");
DatagramPacket packet = new DatagramPacket(data, data.length, address, 5000);

socket.send(packet);
socket.close();

E Winsock che c’entra?

Winsock (Windows Sockets) è la libreria che implementa le API di rete su Windows.
Non la usi direttamente in Java, perché la JVM si occupa di parlare con Winsock per te.

Ma attenzione:

  • se fai programmi nativi in C/C++, userai Winsock (con le funzioni socket(), bind(), send(), ecc.)
  • se usi Java, i socket Java passano comunque da Winsock quando il programma gira su Windows, ma senza che tu debba toccarla

Quindi sì, se il tuo Java gira su Windows, sotto sotto c’è Winsock.
Se invece vuoi scrivere un server in C/C++ da far comunicare con un client Java, allora sì: userai Winsock lato C e Java Socket lato Java.

Conclusione

I socket sono uno dei mattoni fondamentali della comunicazione di rete. Capirli (e usarli) ti apre la porta a un mondo enorme: chat, giochi online, sistemi distribuiti, IoT… tutto passa da lì.

Java rende la vita abbastanza semplice, sia con TCP che con UDP, e se ti capita di lavorare in ambiente Windows, sapere cosa sia Winsock può solo aiutarti a capire cosa succede “dietro le quinte”.