Java/Network Protocol/UDP

Материал из Java эксперт
Перейти к: навигация, поиск

An echo server using UDP sockets

 
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpEchoServer {
  static final int BUFFERSIZE = 256;
  public static void main(String[] args) {
    DatagramSocket sock;
    DatagramPacket pack = new DatagramPacket(new byte[BUFFERSIZE],
        BUFFERSIZE);
    try {
      sock = new DatagramSocket(7);
    } catch (SocketException e) {
      System.out.println(e);
      return;
    }
    // echo back everything
    while (true) {
      try {
        sock.receive(pack);
        sock.send(pack);
      } catch (IOException ioe) {
        System.out.println(ioe);
      }
    }
  }
}





Connect to a daytime server using the UDP protocol

 

/*
 * Copyright (c) 2004 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 3nd Edition.
 * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
 * You may study, use, and modify it for any non-commercial purpose,
 * including teaching and use in open-source projects.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book, 
 * please visit http://www.davidflanagan.ru/javaexamples3.
 */
//package je3.nio;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketTimeoutException;
/**
 * Connect to a daytime server using the UDP protocol. We use java.net instead
 * of java.nio because DatagramChannel doesn"t honor the setSoTimeout() method
 * on the underlying DatagramSocket
 */
public class DaytimeClient {
  public static void main(String args[]) throws java.io.IOException {
    // Figure out the host and port we"re going to talk to
    String host = args[0];
    int port = 13;
    if (args.length > 1)
      port = Integer.parseInt(args[1]);
    // Create a socket to use
    DatagramSocket socket = new DatagramSocket();
    // Specify a 1-second timeout so that receive() does not block forever.
    socket.setSoTimeout(1000);
    // This buffer will hold the response. On overflow, extra bytes are
    // discarded: there is no possibility of a buffer overflow attack here.
    byte[] buffer = new byte[512];
    DatagramPacket packet = new DatagramPacket(buffer, buffer.length, new InetSocketAddress(host,
        port));
    // Try three times before giving up
    for (int i = 0; i < 3; i++) {
      try {
        // Send an empty datagram to the specified host (and port)
        packet.setLength(0); // make the packet empty
        socket.send(packet); // send it out
        // Wait for a response (or timeout after 1 second)
        packet.setLength(buffer.length); // make room for the response
        socket.receive(packet); // wait for the response
        // Decode and print the response
        System.out.print(new String(buffer, 0, packet.getLength(), "US-ASCII"));
        // We were successful so break out of the retry loop
        break;
      } catch (SocketTimeoutException e) {
        // If the receive call timed out, print error and retry
        System.out.println("No response");
      }
    }
    // We"re done with the channel now
    socket.close();
  }
}





DatagramSocket Client

  
import java.net.DatagramPacket;
import java.net.DatagramSocket;
class WriteServer {
  public static void main(String args[]) throws Exception {
    int clientPort = 999;
    int buffer_size = 1024;
    byte buffer[] = new byte[buffer_size];
    DatagramSocket ds = new DatagramSocket(clientPort);
    while (true) {
      DatagramPacket p = new DatagramPacket(buffer, buffer.length);
      ds.receive(p);
      System.out.println(new String(p.getData(), 0, p.getLength()));
    }
  }
}





DatagramSocket Server

  
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
class WriteServer {
  public static void main(String args[]) throws Exception {
    int serverPort = 998;
    int buffer_size = 1024;
    byte buffer[] = new byte[buffer_size];
    DatagramSocket ds = new DatagramSocket(serverPort);
      int pos = 0;
      while (true) {
        int c = System.in.read();
        switch (c) {
        case -1:
          System.out.println("Server Quits.");
          return;
        case "\r":
          break;
        case "\n":
          ds.send(new DatagramPacket(buffer, pos, InetAddress.getLocalHost(), 999));
          pos = 0;
          break;
        default:
          buffer[pos++] = (byte) c;
        }
      }
  }
}





Experiment with UDP sockets

 
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDP0 {
  // command line arguments:
  // r -- read an incoming packet
  // w hostname word -- write word to hostname
  public static void main(String[] args) throws Exception {
    byte[] ary = new byte[128];
    DatagramPacket pack = new DatagramPacket(ary, 128);
    if (args[0].charAt(0) == "r") {
      // read
      DatagramSocket sock = new DatagramSocket(1111);
      sock.receive(pack);
      String word = new String(pack.getData());
      System.out.println("From: " + pack.getAddress() + " Port: "
          + pack.getPort());
      System.out.println(word);
      sock.close();
    } else { // write
      DatagramSocket sock = new DatagramSocket();
      pack.setAddress(InetAddress.getByName(args[1]));
      pack.setData(args[2].getBytes());
      pack.setPort(1111);
      sock.send(pack);
      sock.close();
    }
  }
}





Handles TCP and UDP connections and provides exception handling and error logging

 
 
/*
 * Copyright (c) 2004 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 3nd Edition.
 * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
 * You may study, use, and modify it for any non-commercial purpose,
 * including teaching and use in open-source projects.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book, 
 * please visit http://www.davidflanagan.ru/javaexamples3.
 */
//package je3.nio;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.Channel;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * A more robust daytime service, that handles TCP and UDP connections and
 * provides exception handling and error logging.
 */
public class DaytimeServer {
  public static void main(String args[]) {
    try { // Handle startup exceptions at the end of this block
      // Get an encoder for converting strings to bytes
      CharsetEncoder encoder = Charset.forName("US-ASCII").newEncoder();
      // Allow an alternative port for testing with non-root accounts
      int port = 13; // RFC867 specifies this port.
      if (args.length > 0)
        port = Integer.parseInt(args[0]);
      // The port we"ll listen on
      SocketAddress localport = new InetSocketAddress(port);
      // Create and bind a tcp channel to listen for connections on.
      ServerSocketChannel tcpserver = ServerSocketChannel.open();
      tcpserver.socket().bind(localport);
      // Also create and bind a DatagramChannel to listen on.
      DatagramChannel udpserver = DatagramChannel.open();
      udpserver.socket().bind(localport);
      // Specify non-blocking mode for both channels, since our
      // Selector object will be doing the blocking for us.
      tcpserver.configureBlocking(false);
      udpserver.configureBlocking(false);
      // The Selector object is what allows us to block while waiting
      // for activity on either of the two channels.
      Selector selector = Selector.open();
      // Register the channels with the selector, and specify what
      // conditions (a connection ready to accept, a datagram ready
      // to read) we"d like the Selector to wake up for.
      // These methods return SelectionKey objects, which we don"t
      // need to retain in this example.
      tcpserver.register(selector, SelectionKey.OP_ACCEPT);
      udpserver.register(selector, SelectionKey.OP_READ);
      // This is an empty byte buffer to receive emtpy datagrams with.
      // If a datagram overflows the receive buffer size, the extra bytes
      // are automatically discarded, so we don"t have to worry about
      // buffer overflow attacks here.
      ByteBuffer receiveBuffer = ByteBuffer.allocate(0);
      // Now loop forever, processing client connections
      for (;;) {
        try { // Handle per-connection problems below
          // Wait for a client to connect
          selector.select();
          // If we get here, a client has probably connected, so
          // put our response into a ByteBuffer.
          String date = new java.util.Date().toString() + "\r\n";
          ByteBuffer response = encoder.encode(CharBuffer.wrap(date));
          // Get the SelectionKey objects for the channels that have
          // activity on them. These are the keys returned by the
          // register() methods above. They are returned in a
          // java.util.Set.
          Set keys = selector.selectedKeys();
          // Iterate through the Set of keys.
          for (Iterator i = keys.iterator(); i.hasNext();) {
            // Get a key from the set, and remove it from the set
            SelectionKey key = (SelectionKey) i.next();
            i.remove();
            // Get the channel associated with the key
            Channel c = (Channel) key.channel();
            // Now test the key and the channel to find out
            // whether something happend on the TCP or UDP channel
            if (key.isAcceptable() && c == tcpserver) {
              // A client has attempted to connect via TCP.
              // Accept the connection now.
              SocketChannel client = tcpserver.accept();
              // If we accepted the connection successfully,
              // the send our respone back to the client.
              if (client != null) {
                client.write(response); // send respone
                client.close(); // close connection
              }
            } else if (key.isReadable() && c == udpserver) {
              // A UDP datagram is waiting. Receive it now,
              // noting the address it was sent from.
              SocketAddress clientAddress = udpserver.receive(receiveBuffer);
              // If we got the datagram successfully, send
              // the date and time in a response packet.
              if (clientAddress != null)
                udpserver.send(response, clientAddress);
            }
          }
        } catch (java.io.IOException e) {
          // This is a (hopefully transient) problem with a single
          // connection: we log the error, but continue running.
          // We use our classname for the logger so that a sysadmin
          // can configure logging for this server independently
          // of other programs.
          Logger l = Logger.getLogger(DaytimeServer.class.getName());
          l.log(Level.WARNING, "IOException in DaytimeServer", e);
        } catch (Throwable t) {
          // If anything else goes wrong (out of memory, for example)
          // then log the problem and exit.
          Logger l = Logger.getLogger(DaytimeServer.class.getName());
          l.log(Level.SEVERE, "FATAL error in DaytimeServer", t);
          System.exit(1);
        }
      }
    } catch (Exception e) {
      // This is a startup error: there is no need to log it;
      // just print a message and exit
      System.err.println(e);
      System.exit(1);
    }
  }
}





Receive UDP pockets

 
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPReceive {
  public static void main(String args[]) {
    try {
      int port = 90;
      // Create a socket to listen on the port.
      DatagramSocket dsocket = new DatagramSocket(port);
      // Create a buffer to read datagrams into. If a
      // packet is larger than this buffer, the
      // excess will simply be discarded!
      byte[] buffer = new byte[2048];
      // Create a packet to receive data into the buffer
      DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
      // Now loop forever, waiting to receive packets and printing them.
      while (true) {
        // Wait to receive a datagram
        dsocket.receive(packet);
        // Convert the contents to a string, and display them
        String msg = new String(buffer, 0, packet.getLength());
        System.out.println(packet.getAddress().getHostName() + ": "
            + msg);
        // Reset the length of the packet before reusing it.
        packet.setLength(buffer.length);
      }
    } catch (Exception e) {
      System.err.println(e);
    }
  }
}





Send out UDP pockets

 
import java.io.*;
import java.net.*;
public class UDPSend {
  public static void main(String args[]) {
    try {
      String host = "www.jexp.ru";
      int port = 90;
      byte[] message = "Java Source and Support".getBytes();
      // Get the internet address of the specified host
      InetAddress address = InetAddress.getByName(host);
      // Initialize a datagram packet with data and address
      DatagramPacket packet = new DatagramPacket(message, message.length,
          address, port);
      // Create a datagram socket, send the packet through it, close it.
      DatagramSocket dsocket = new DatagramSocket();
      dsocket.send(packet);
      dsocket.close();
    } catch (Exception e) {
      System.err.println(e);
    }
  }
}





Udp Echo Server

 
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Main {
  static final int BUFFERSIZE = 256;
  public static void main(String[] args) throws Exception {
    DatagramPacket pack = new DatagramPacket(new byte[BUFFERSIZE], BUFFERSIZE);
    DatagramSocket sock = new DatagramSocket(7);
    // echo back everything
    while (true) {
      sock.receive(pack);
      sock.send(pack);
    }
  }
}





Using Datagrams to Get the Date

 
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class GetDate {
  final static int PortDayTime = 13; // well-known daytime port
  public static void main(String args[]) throws Exception {
    byte msg[] = new byte[256];
    DatagramSocket dgSocket = new DatagramSocket();
    InetAddress destination = InetAddress.getByName("web.mit.edu");
    DatagramPacket datagram = new DatagramPacket(msg, msg.length,
        destination, PortDayTime);
    dgSocket.send(datagram);
    datagram = new DatagramPacket(msg, msg.length);
    dgSocket.receive(datagram);
    String received = new String(datagram.getData());
    System.out.println("The time in Cambridge is now: " + received);
    dgSocket.close();
  }
}