Java/Network Protocol/UDP
Содержание
- 1 An echo server using UDP sockets
- 2 Connect to a daytime server using the UDP protocol
- 3 DatagramSocket Client
- 4 DatagramSocket Server
- 5 Experiment with UDP sockets
- 6 Handles TCP and UDP connections and provides exception handling and error logging
- 7 Receive UDP pockets
- 8 Send out UDP pockets
- 9 Udp Echo Server
- 10 Using Datagrams to Get the Date
An echo server using UDP sockets
<source lang="java">
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); } } }
}
</source>
Connect to a daytime server using the UDP protocol
<source lang="java">
/*
* 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(); }
}
</source>
DatagramSocket Client
<source lang="java">
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())); } }
}
</source>
DatagramSocket Server
<source lang="java">
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; } } }
}
</source>
Experiment with UDP sockets
<source lang="java">
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(); } }
}
</source>
Handles TCP and UDP connections and provides exception handling and error logging
<source lang="java">
/*
* 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); } }
}
</source>
Receive UDP pockets
<source lang="java">
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); } }
}
</source>
Send out UDP pockets
<source lang="java">
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); } }
}
</source>
Udp Echo Server
<source lang="java">
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); } }
}
</source>
Using Datagrams to Get the Date
<source lang="java">
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(); }
}
</source>