Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Datagrammi e Socket Multicast in Java: Guida e Implementazione - Prof. Coen Porisini, Appunti di Elementi di Informatica

Una panoramica dettagliata sull'utilizzo dei datagrammi e dei socket multicast in java. Esplora la creazione e la gestione dei datagrammi, la conversione dei tipi di dati in byte array e l'implementazione di server e client multicast. Include esempi di codice per illustrare i concetti chiave, come l'invio e la ricezione di pacchetti, la gestione degli indirizzi ip e delle porte, e la sottoscrizione a gruppi multicast. Utile per studenti e sviluppatori che desiderano comprendere e implementare comunicazioni di rete basate su datagrammi e multicast in java, offrendo una guida pratica e teorica.

Tipologia: Appunti

2024/2025

In vendita dal 15/11/2025

AriBab
AriBab 🇮🇹

88 documenti

1 / 20

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
Programmazione concorrente e distribuita
07/04/2025
Socket UDP
L'alternativa al protocollo TCP è il protocollo UDP (user Datagram Protocol):
Non garantisce che i pacchetti siano consegnati;
Non garantisce che i pacchetti arrivino nell'ordine in cui sono stati inviati;
Raffrontro:
TCP
I client e i Server che comunicano tramite un socket TCP, hanno un canale point-to poitn
dedicato.
Per comunciare, le parti devono stabilire una connessione che a seguito della trasmissione dei
dati verrà chiusa.
Tutti i dati inviati sulc anale vengono ricevuti nello stesso ordine in cui sono stati inviati.
L'invio e il ricevimento di informazioni è sempre garantito.
UDP
Al contrario, le applicazioni che comunicano tramite protocollo UDP inviano e ricevono
pacchetti di informazioni completamente indipendenti.
Questi client e server non dispongono e non necessitano di un canale point-to-point dedicato.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14

Anteprima parziale del testo

Scarica Datagrammi e Socket Multicast in Java: Guida e Implementazione - Prof. Coen Porisini e più Appunti in PDF di Elementi di Informatica solo su Docsity!

Programmazione concorrente e distribuita

Socket UDP

L'alternativa al protocollo TCP è il protocollo UDP (user Datagram Protocol):

  • Non garantisce che i pacchetti siano consegnati;
  • Non garantisce che i pacchetti arrivino nell'ordine in cui sono stati inviati; Raffrontro: TCP I client e i Server che comunicano tramite un socket TCP, hanno un canale point-to poitn dedicato. Per comunciare, le parti devono stabilire una connessione che a seguito della trasmissione dei dati verrà chiusa. Tutti i dati inviati sulc anale vengono ricevuti nello stesso ordine in cui sono stati inviati. L'invio e il ricevimento di informazioni è sempre garantito. UDP Al contrario, le applicazioni che comunicano tramite protocollo UDP inviano e ricevono pacchetti di informazioni completamente indipendenti. Questi client e server non dispongono e non necessitano di un canale point-to-point dedicato.

La consegna dei dataframe a destinazione non è garantita. Anche l'ordine di arrivo non è necessariamente rispettato.

UDP in Java

Un datagram è un messaggio che contiene tutto al suo interno ed è indipendente. Viene mandato lungo la rete, il cuia arrivo, tempo e contenuto non sono garantiti (affidabilità molto bassa). Nel socket java.net ci sono 3 classi da utilizzare:

  • DatagramSocket e DatagramPacket : Servono a raprpesentare l'oggetto da far viaggiare lungo la rete e l'interfaccia di comunicazione da usare per inviare e ricevere;
  • MulticastSocket : Permette di mandare i DataGram a più di un destinatario;

La classe DatagramPacket

Si tratta della classe che rappresenta il pacchetto che può essere inviato / ricevuto), i dati contenuti sono dei byte. I costruttori più importanti sono:

  • DatagramPacket ( byte[] buf, int length): Istanzia un DataGram contenente length byte messix all'interno dell'array buf;
  • Datagrampacket (byte[] buf, int length, InetAddress addess, int port) : Istanzia un Datagram contenente legth byte messi all'interno dell'array buf da inviare alla porta port del

Un server che riceve una sequenza di numeri interi e scrive sullo standard output i valori letti e la loro somma. Ad ogni valore ricevuto scrive i risultati. Poichè la comunicazione è a senso unico (client --> server) e qualora la perdita di qualche dato non comporti grossi problemi si può isare una connessione UDP. Il pacchetto (datagram) deve contenere il numero intero da inviare.

Problema

Il contenuto di un DatagramPacket è un vettore di byte:

  • Bisogna convertire un valore di tipo int in un byte[]

Soluzione

Sfruttiamo il vincolo relativo ai valori numerici generati: "Un client che genera 10 numeri casuali compresi tra 1 e 100.. " è sufficente 1 byte che rappresenta gli interi compresi tra - 128 e + 127 Usiamo il metodo della classe Integer: byte byteValue() public byte byteValue(): Restituisce il valore dell'oggetto intero dopo aver effettuato una conversione che restringe.

Questo tipo di conversione può causare perdita di informazioni in quanto di eliminano tutti i bit ulteriori rispetto a quelli che possono essere rappresentati (un intero che richiede 4 byte viene modellato in 1 solo byte perdo 3 byte).

Soluzione - Scrittura

int n Integer Integer.valueOf (n) byte (Integer.valueOf(n)).byteValue()

Soluzione - Lettura

byte b Byte Byte.valueOf (b) int (Byte.valueOf(n)).intValue()

Client

import java.io.; import java.util.Random; import java.net.; public class** Client { private static final int MAX = 100; private static final String host = "localhost"; public static voi d main(String[] args) throws IOException, InterruptedException { InetAddress addr = InetAddress.getByName(host);

Domande

  • Che cosa succede se il Client parte ma il server non è attivo o si interrompe? Il Client continua a funzionare senza accorgersi che i suoi pacchetti vengono persi (protocollo connection-less);
  • Cosa succede se vi sono più Client attivi contemporanemanete? Il Server accetta tutti i pacchetti che gli arrivano, indipendentemente da chi li invia.

Esempio esteso

Immaginiamo che il server ogni volta che calcola una nuova somma la voglia inviare a dei processi interessati, detti verificatori. A questo punto il nostro sistema è composto da tre tipologie di processi:

  • Client : Generano dei numeri casuali e li inviano al Server (n instaze);
  • Server : Riceve i numeri casuali e li somma, trasmette la somma ai verificatori;
  • Verificatori : Sono interessati a ricevere le somme inviate dal Server;

Discussione

Prima di procedere bisogna affrontare due aspetti chiave riguardo alla presenza dei verificatori:

  • I valori inviati dal server ai verificatori sono il risulatto delle somme: ◦ Non sono più rappresentabili attraverso un singolo byte inq uanto possono esssere maggiori di 128;
  • Il numero di verificatori non è noto al server;

Problema 1

Non possiamo più usare 1 solo byte per rappresentare gli interi perchè i valori tramessi potrebbero non essere all'interno dell'intervallo [-128; 127]. Il contenuto di un DatagramPacket è un vettore di byte:

  • Bisgona convertire un valore di tipo int in un yte[]: ◦ In Java un intero è rappresentabile da 4 byte;

Soluzione

Trasformare un int in un byte[4] è necessario specificare la modalità di codifica:

  • Big-Endian : Il byte più significativo è l'ultimo;
  • Little-Endian : Il Byte più significativo è il primo; Usiamo la classe ByteBuffer definita nel package java.nio
  • static ByteBuffer allocate(int capacity) : Alloco un nuovo buffer di dimensione specificata dal parametro
  • static ByteBuffer wrap(byte[] array) : Costruisce un oggetto di tipo ByteBuffer a partire da un vettore di byte;
  • byte[] array() : Ritorna il vettore di byte;
  • abstract int getInt(): Estrea il valore intero;

riceverla, si definisce il gruppo di coloroc he sono interessati.

Multicast

La tramissione multicast, per convenzione devono essere indirizzare a un indirizzo IP compreso tra:

  • 224.0.0.0;
  • 239.255.255.255; In particolare l'intervallo 224.0.0.0 - 224.0.0. è riservato all'utilizzo nell'ambito di sotto-reti private, non vengono noltrati all'esterno dai router. In Java la classe MulticastSocket consente di inviare dei DatagramPacket in modalità multicast, ossia a tutti coloro che sono interessati a riceverli. Chi invia e coloro che vogliono ricevere devono far parte di uno stesso gruppo.

La classe MulticastSocket

Costruttore principale: MulticastSocket (int port) Per inviare e ricevere datagram si usano i seguenti metodo:

  • void send (DatagramPacket p): Per spedire un pacchetto;
  • void receive (DatagramPacket p) : per ricevere un pacchetto;

La definizione di un gruppo e la sottoscrizione ad esso è più macchinosa e si basa su seguente metodo: void joinGroup (SocketAddress mcstaddr, Networkinterface ne) SocketAddress è una classe astratta rappresentante l'indirizzo del Socket:

  • è atratta in quanto non viene definito il protocollo;
  • La classe InetSocketAddress è una classe discendente che implementa il protocollo IP, il cui costruttore è: InetSocektAsddress(InetAddress addr, int port) NetworkInterface è una classe che rappresenta le interfacce di rete:
  • è costituita da un nome e da una lista di indirizzi IP assegnati all'interfaccia;
  • Si ottiene grazie al metodo statico: NetworkInterface getByInetAddress(intAddress addr)

Il server multicast

Il server userà l'indirizzo 224.0.0.1 e la porta 18002 per il multicast. Definiamo la seguenti costanti: public static final int portOut = 18002; public static final String mtcAddr = "224.0.0.1"; Il server continuerà a usare la porta 18001 per ricevere i datagram che arrivano dai client:

public class ServerMultiCast { public static final int port = 18001; public static final int portOut = 18002; public static final String mtcAddr = "224.0.0.1"; public static void main(String[] args) throws Exception { DatagramSocket dsIn = new DatagramSocket(port); MulticastSocket mcs = new MulticastSocket(portOut); InetSocketAddress iaddr = new InetSocketAddress(mtcAddr,portOut); InetAddress group = InetAddress.getByName(mtcAddr); mcs.joinGroup(iaddr, NetworkInterface.getByInetAddress(group)); int somma = 0, val = 0; byte[] buf = new byte[1]; while(true){ Thread.sleep(2000); DatagramPacket p = new DatagramPacket(buf, buf.length); dsIn.receive(p); buf = p.getData(); val = (Byte.valueOf(buf[0])).intValue(); somma += val; System.out.println("Letto: " + val +"; Somma: " + somma); byte[] tmp = my_int_to_bb_be(somma); DatagramPacket out = new DatagramPacket(tmp,tmp.length,group,portOut); mcs.send(out); } } private static byte[] my_int_to_bb_be(int myInteger){ ByteBuffer tmpbb = ByteBuffer.allocate(4); tmpbb.order(ByteOrder.BIG_ENDIAN); tmpbb.putInteger(myInteger); return(tmpbb.array()); } }

Il verificatore

Per ricevere i multicast istanzia un oggetto di classe MulticastSocket sulla porta: ServerMulticast.portOut (18002) MulticastScoket mcs = new MulticastSocket(ServerMulticast.portOut); Il gruppo cui aderire viene definito nel seguente modo. Si costruisce un oggetto InetSocketAddress con:

  • Indirizzo IP = ServerMultiCast.mctAddr (224.0.0.1)
  • porta = ServerMultiCast.portOut (18002); InetSocketAddress iaddr = new InetSocketAddress( ServerMultiCast.mtcAddr, ServerMultiCast.portOut); Si costruisce un oggetto InetAddress rappresentante l'indirizzo IP del gruppo da cui arrivano i datagram: InetAddress group = InterAddress.getByName(ServerMultiCast mtcAddr); Si sottoscrive l'appartenenza al gruppo: mcs.joinGroup (iaddr, NetworkInterface.getByInetAddress (group)); public class Verificatore { public static void main(String[] args) throws IOException { MulticastSocket mcs = new MulticastSocket(ServerMultiCast.portOut); InetSocketAddress iaddr =

InetAddress addr = InetAddress.getByName(host); Random rG = new Random(); DatagramSocket ds = new DatagramSocket(); byte[] buf = new byte[1]; int num; for(int i=1; i<11; i++) { num = rG.nextInt(MAX); System.out.println("Generato " + num); buf[0] = (Integer.valueOf(num)).byteValue(); DatagramPacket data = new DatagramPacket(buf,buf.length,addr, ServerMultiCast.port); System.out.println("Client invia a " + data.getAddress() + " Porta: " + data.getPort()); ds.send(data); Thread.sleep(1000); } ds.close(); } }

ServerMulticast

public class ServerMultiCast { public static final int port = 18001; public static final int portOut = 18002; public static final String mtcAddr = "224.0.0.1"; public static void main(String[] args) throws Exception { DatagramSocket dsIn = new DatagramSocket(port); MulticastSocket mcs = new MulticastSocket(portOut); InetSocketAddress iaddr = new InetSocketAddress(mtcAddr,portOut); InetAddress group = InetAddress.getByName(mtcAddr); mcs.joinGroup(iaddr, NetworkInterface.getByInetAddress(group)); int somma = 0, val = 0;

byte[] buf = new byte[1]; while(true){ Thread.sleep(2000); DatagramPacket p = new DatagramPacket(buf, buf.length); dsIn.receive(p); buf = p.getData(); System.out.println("Server riceve da: " + p.getAddress() + " Porta: "+ p.getPort()); val = (Byte.valueOf(buf[0])).intValue(); somma += val; System.out.println("Letto: " + val +"; Somma: " + somma); byte[] tmp = my_int_to_bb_be(somma); DatagramPacket out = new DatagramPacket(tmp,tmp.length,group,portOut); mcs.send(out); System.out.println("Server invia a " + out.getAddress() + " Porta: " + out.getPort()); } }

Verificatore

public class Verificatore { public static void main(String[] args) throws IOException { MulticastSocket mcs = new MulticastSocket(ServerMultiCast.portOut); InetSocketAddress iaddr = new InetSocketAddress(ServerMultiCast.mtcAddr, ServerMultiCast.portOut); InetAddress group = InetAddress.getByName(ServerMultiCast.mtcAddr); mcs.joinGroup(iaddr, NetworkInterface.getByInetAddress(group)); byte[] buf = new byte[4]; int num; while (true) { DatagramPacket data = new DatagramPacket(buf,4); mcs.receive(data); System.out.println("Verificatore riceve da:" +

Random rG = new Random(); DatagramSocket ds = new DatagramSocket(); byte[] buf = new byte[1]; int num;

Contenuto dei pacchetti

Dipende dal costruttore di DatagramSocket del Client. Quello che vediamo è il valore restituito dal metodo int getLocalPort():

  • è la porta associata al DatagramSocket del clinet;
  • la porta 18001 è giù usata dal Server: ◦ Client e Server sono sulla stessa macchina;

Contenuto dei pacchetti

Generato dal client Generato dal Server Indirizzo: 224.0.0.1 Indirizzo: 10.0.0. Porta: 180012 Porta: 18002 Indirizo: 224.0.01 Indirizzo: 10.0.0. Porta: 18002 Porta: 18002 In questo caso la corrispondenza è tra:

  • Il pacchetto in partenza che riporta come c ad un indirizzo multicast 224.0.0.1;
  • Il pacchetto in arrivo che riporta come indirizo quello della macchian da cui è partito 10.0.0.11;