User Datagram Protocol (UDP)

Il est utilisé quand il est nécessaire soit de transmettre des données très rapidement, et où la perte d'une partie de ces données n'a pas grande importance, soit de transmettre des petites quantités de données, là où la connexion TCP serait inutilement coûteuse en ressources.

Exemple d'utilisation

DatagramPacket et DatagramSocket sont les deux principales classes utilisées pour implémenter une application client/serveur UDP. DatagramPacket est un conteneur de données transférées et DatagramSocket est un mécanisme pour envoyer et recevoir des DatagramPackets.

DatagramPacket


Selon les termes d'UDP, les données transférées sont encapsulées dans une unité appelée datagramme. Un datagramme est un message indépendant et autonome envoyé sur le réseau dont l'arrivée, l'heure d'arrivée et le contenu ne sont pas garantis. Et en Java, DatagramPacket représente un datagramme.

L'UDP fonctionne en encapsulant les données dans le paquet et en fournissant ses propres informations d'en-tête au paquet.


Datagram format

0                        15 16                          31
port UDP source port UDP destination
longueur somme de contrôle
data

Ensuite, ce paquet UDP est encapsulé dans le paquet IP et envoyé à sa destination

En-tête IP Datagram 



DatagramSocket

Le  DatagramSocket est utilisé pour envoyer et recevoir des DatagramPackets. DatagramSocket représente une connexion UDP entre deux ordinateurs dans un réseau.
En Java on utilise  DatagramSocket pour le client et le serveur. Il n'y a pas de classes distinctes pour le client et le serveur comme les sockets TCP.



DatagramSocket - mis sur le serveur et sur le client 

Exemple

1) utilitaire de convertion String -> DatagramPacket
                                            DatagramPacket -> String
 
import java.net.*;
public class Dgram {
     public static DatagramPacket toDatagram(String s, InetAddress destIA, int destPort) {
          byte[] buf = s.getBytes();
          return new DatagramPacket(buf, buf.length, destIA, destPort);
    }
     public static String toString(DatagramPacket p){
          return  new String(p.getData(), 0, p.getLength());
    }
}

2) Le serveur
 
import java.net.*;
import java.io.*;
import java.util.*;

public class DGServer {
  static final int INPORT = 9090;
  private byte[] buf = new byte[1000];
  private DatagramPacket dp = new DatagramPacket(buf, buf.length);
  // Can listen & send on the same socket:
  private DatagramSocket socket;

  public DGServer() {
    try {
      socket = new DatagramSocket(INPORT);
      System.out.println("Server started");
      while(true) {
        // Block until a datagram appears:
        socket.receive(dp);
        String rcvd = Dgram.toString(dp) +
          ", from address: " + dp.getAddress() +
          ", port: " + dp.getPort();
 

        System.out.println(rcvd);
        String echoString = 
          "Echoed: " + rcvd;
        // Extract the address and port from the
        // received datagram to find out where to
        // send it back:
        DatagramPacket echo = 
          Dgram.toDatagram(echoString,
            dp.getAddress(), dp.getPort());
        socket.send(echo);
      }
    } catch(SocketException e) {
      System.err.println("Can't open socket");
      System.exit(1);
    } catch(IOException e) {
      System.err.println("Communication error");
      e.printStackTrace();
    }
  }
  public static void main(String[] args) {
    new DGServer();
  }

3) Le client (Chaque client fonctionne avec son propre socket)
 
 
import java.net.*;
import java.io.*;

public class DGClient extends Thread {
  // Can listen & send on the same socket:
  static final int INPORT = 9090;
  private DatagramSocket s;
  private InetAddress hostAddress;
  private byte[] buf = new byte[1000];
  private DatagramPacket dp = 
    new DatagramPacket(buf, buf.length);
  private int id;

  public DGClient(int identifier) {
    id = identifier;
    try {
      // Auto-assign port number:
      s = new DatagramSocket();
      hostAddress = 
        InetAddress.getByName("localhost");
    } catch(UnknownHostException e) {
      System.err.println("Cannot find host");
      System.exit(1);
    } catch(SocketException e) {
      System.err.println("Can't open socket");
      e.printStackTrace();
      System.exit(1);
    } 
    System.out.println("DGClient starting");
  }

  public void run() {
    try {
      for(int i = 0; i < 25; i++) {
        String outMessage = "Client #" +
          id + ", message #" + i;
        // Make and send a datagram:
        s.send(Dgram.toDatagram(outMessage,
          hostAddress, 
          INPORT));
        // Block until it echoes back:
        s.receive(dp);
        // Print out the echoed contents:
        String rcvd = "Client #" + id +
          ", rcvd from " + 
          dp.getAddress() + ", " + 
          dp.getPort() + ": " +
          Dgram.toString(dp);
        System.out.println(rcvd);
      }
    } catch(IOException e) {
      e.printStackTrace();
      System.exit(1);
    }
  }
  public static void main(String[] args) {
    for(int i = 0; i < 10; i++)
      new DGClient(i).start();
  }


4) Modifiez le client à fin que tous les threads utilisent un seul socket