5.3.5 – Comunicazione con TCP/UDP – Realizzazione di un server/client TCP/UDP in Java

Obiettivi della lezione:

  • Comprendere i protocolli TCP e UDP. Gli studenti impareranno le differenze tra i protocolli TCP e UDP e i loro usi appropriati nelle applicazioni di rete.
  • Implementare un server e un client TCP in Java. Gli studenti acquisiranno competenze pratiche nella creazione di una comunicazione affidabile tra server e client utilizzando TCP.
  • Implementare un server e un client UDP in Java. Gli studenti impareranno a creare una comunicazione non affidabile ma veloce utilizzando UDP.

Introduzione ai protocolli TCP e UDP

TCP (Transmission Control Protocol)

TCP è un protocollo di trasporto orientato alla connessione che fornisce una comunicazione affidabile tra due endpoint. TCP garantisce che i dati inviati dal mittente vengano ricevuti correttamente dal destinatario, grazie a meccanismi di controllo del flusso, rilevamento degli errori e ritrasmissione dei pacchetti persi.

  • Caratteristiche principali:
  • Affidabile: garantisce la consegna dei dati senza errori e nell’ordine corretto.
  • Controllo del flusso: regola la velocità di trasmissione dei dati per evitare la congestione della rete.
  • Controllo degli errori: utilizza checksum e numeri di sequenza per rilevare e correggere gli errori di trasmissione.

UDP (User Datagram Protocol)

UDP è un protocollo di trasporto non orientato alla connessione che fornisce una comunicazione rapida ma non garantisce la consegna affidabile dei dati. UDP è adatto per applicazioni che richiedono velocità e tollerano la perdita di pacchetti, come lo streaming video e i giochi online.

  • Caratteristiche principali:
  • Non affidabile: non garantisce la consegna dei dati né l’ordine corretto.
  • Leggero: ha un overhead minimo rispetto a TCP, rendendolo più veloce.
  • Nessun controllo del flusso o degli errori: i pacchetti vengono inviati senza verifiche aggiuntive.

Implementazione di un server e client TCP in Java

Server TCP

  1. Codice del server TCP:
import java.io.*;
import java.net.*;

public class TCPServer {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(6789)) {
            System.out.println("Server avviato e in attesa di connessioni...");

            while (true) {
                try (Socket connectionSocket = serverSocket.accept();
                     BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
                     DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream())) {

                    String clientSentence = inFromClient.readLine();
                    System.out.println("Ricevuto: " + clientSentence);
                    String capitalizedSentence = clientSentence.toUpperCase() + '\n';
                    outToClient.writeBytes(capitalizedSentence);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Client TCP

  1. Codice del client TCP:
import java.io.*;
import java.net.*;

public class TCPClient {
    public static void main(String[] args) {
        String serverAddress = "localhost";
        int serverPort = 6789;

        try (Socket clientSocket = new Socket(serverAddress, serverPort);
             BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
             DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
             BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {

            System.out.print("Inserisci un messaggio: ");
            String sentence = inFromUser.readLine();
            outToServer.writeBytes(sentence + '\n');
            String modifiedSentence = inFromServer.readLine();
            System.out.println("Dal server: " + modifiedSentence);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Implementazione di un server e client UDP in Java

Server UDP

  1. Codice del server UDP:
import java.net.*;

public class UDPServer {
    public static void main(String[] args) {
        try (DatagramSocket serverSocket = new DatagramSocket(9876)) {
            byte[] receiveData = new byte[1024];
            byte[] sendData = new byte[1024];

            while (true) {
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                serverSocket.receive(receivePacket);
                String sentence = new String(receivePacket.getData(), 0, receivePacket.getLength());
                System.out.println("Ricevuto: " + sentence);

                InetAddress clientAddress = receivePacket.getAddress();
                int clientPort = receivePacket.getPort();
                String capitalizedSentence = sentence.toUpperCase();
                sendData = capitalizedSentence.getBytes();
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, clientAddress, clientPort);
                serverSocket.send(sendPacket);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Client UDP

  1. Codice del client UDP:
import java.net.*;

public class UDPClient {
    public static void main(String[] args) {
        String serverAddress = "localhost";
        int serverPort = 9876;

        try (DatagramSocket clientSocket = new DatagramSocket()) {
            InetAddress IPAddress = InetAddress.getByName(serverAddress);
            byte[] sendData = new byte[1024];
            byte[] receiveData = new byte[1024];

            String sentence = "Ciao server UDP";
            sendData = sentence.getBytes();
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, serverPort);
            clientSocket.send(sendPacket);

            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            clientSocket.receive(receivePacket);
            String modifiedSentence = new String(receivePacket.getData(), 0, receivePacket.getLength());
            System.out.println("Dal server: " + modifiedSentence);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Esercitazioni pratiche

  1. Implementazione di un server e client TCP:
  • Creare un server TCP che accetta connessioni dai client e converte i messaggi ricevuti in maiuscolo.
  • Creare un client TCP che invia messaggi al server e visualizza la risposta convertita in maiuscolo.
  • Testare la comunicazione tra server e client in locale e in rete.
  1. Implementazione di un server e client UDP:
  • Creare un server UDP che riceve messaggi dai client e converte i messaggi ricevuti in maiuscolo.
  • Creare un client UDP che invia messaggi al server e visualizza la risposta convertita in maiuscolo.
  • Testare la comunicazione tra server e client in locale e in rete.
  1. Confronto tra TCP e UDP:
  • Eseguire test di comunicazione utilizzando sia TCP che UDP e confrontare le prestazioni in termini di velocità e affidabilità.
  • Documentare le osservazioni e discutere i casi d’uso appropriati per ciascun protocollo.