User Datagram Protocol (UDP)

DatagramSocket - върху сървъра и върху клиента
 

Пример:

1) Помощен инструмент за конвертиране  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) Сървър
 
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) Клиент
 
 
import java.lang.Thread;
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();
  }

  Упражнение 1: Да се използват горните класове за направа на "chat" сървър и клиенти. Съобщенията от всеки клиент  да бъдат препращани на всички клиенти регистрирани в момента. Клиентите да имат имена и да се отписват от сървъра със специално съобщение - например "bye".
 
  Упражнение 2: Направете клиентите да работят в два отделни прозореца - единия в който клиентът пише а другия - в който се получават съобщенията от сървъра.