Java/Network Protocol/UDP
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
- 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
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();
}
}