Lecture 06 UDP Programming
Lecture 06 UDP Programming
Lecture 06 UDP Programming
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
<strong>Lecture</strong> <strong>06</strong><br />
<strong>UDP</strong> <strong>Programming</strong><br />
CSIE33000<br />
Network <strong>Programming</strong> in Java<br />
Why <strong>UDP</strong>?<br />
• TCP incurs connection overhead which is not<br />
appropriate p for app making small exchange.<br />
• The delivery guarantee of TCP can be a bad<br />
fit for real-time applications (av streaming).<br />
• User Datagram Protocol (<strong>UDP</strong>) provides a<br />
connectionless, best-effor datagram<br />
transport service.<br />
• A very thin layer on top of IP with port<br />
addressing and payload integrity verification.<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 2<br />
Shiow-yang Wu Note 1
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
How about Using IP Directly?<br />
• IP does not verify the integrity of the<br />
datagram data payload.<br />
• The destination of an IP datagram is an IP<br />
address. Can’t distinguish between<br />
datagram of different applications. Protocolspecific<br />
application addressing is needed.<br />
• Allowing applications i access to raw IP<br />
transmission is considered dangerous from a<br />
security standpoint.<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 3<br />
User Datagram Protocol (<strong>UDP</strong>)<br />
• connectionless, best-effort service (RFC768)<br />
• Destination port addressing: same as TCP<br />
port number (16-bit value, 0~65535)<br />
• Data payload integrity verification<br />
• associate a 16-bit checksum with each datagram<br />
• one’s complement checksum algorithm (catches<br />
all single bit-errors and many multiple-bit errors)<br />
• Source port identification<br />
• store the source port number in each datagram<br />
• to provide a return address (with IP address)<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 4<br />
Shiow-yang Wu Note 2
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
<strong>UDP</strong> Datagram Structure<br />
4 bytes<br />
IP<br />
Header<br />
<strong>UDP</strong><br />
Header<br />
<strong>UDP</strong><br />
Payload<br />
Ver IHL TOS<br />
Total length<br />
Identification Flag Frag Ofset<br />
TTL Protocol Header checksum<br />
Source Address<br />
Destination Address<br />
Variable-size IP Options<br />
source port<br />
destination port<br />
length<br />
checksum<br />
data (bytes)<br />
20 bytes<br />
0-40 bytes<br />
8 bytes<br />
up to<br />
65508<br />
bytes<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 5<br />
<strong>UDP</strong> Operations<br />
IP Payload<br />
IP Header<br />
Destination Port:37 Destination:3139.52.12.2<br />
39 “What is the Source Port:4321 Source:128.59.22.38<br />
time?” Checksum Protocol:<strong>UDP</strong><br />
<strong>UDP</strong> Time<br />
Client<br />
<strong>UDP</strong> Payload<br />
<strong>UDP</strong> Header<br />
best effort<br />
<strong>UDP</strong> Time<br />
Server<br />
bind(4321,<br />
<strong>UDP</strong>) Host A<br />
128.59.22.38<br />
CSIE33000 Network <strong>Programming</strong><br />
Internet<br />
(IP)<br />
Host B<br />
139.52.12.2<br />
bind(37,<br />
<strong>UDP</strong>)<br />
<strong>UDP</strong> <strong>Programming</strong> 6<br />
Shiow-yang Wu Note 3
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
<strong>UDP</strong> vs. TCP<br />
TCP Main Functions<br />
• Packet ordering<br />
• Reliable transmission<br />
• Streaming abstraction<br />
• Flow control<br />
• Congestion control<br />
⇒ Good for services that<br />
need to exchange large<br />
amounts data in a reliable<br />
manner w/o real-time<br />
constraints<br />
<strong>UDP</strong> App Characteristics<br />
• Small requests and replies<br />
• Read-only/re-entrant<br />
servers<br />
• Stateless servers<br />
• Real-time streaming<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 7<br />
Common <strong>UDP</strong>-based Applications<br />
• Domain Name System (DNS)<br />
• Simple Network Management Protocol (SNMP)<br />
• Trivial File Transfer Protocol (TFTP)<br />
• Network File Systems (NFS)<br />
• Network Time Protocol (NTP)<br />
• Real Audio<br />
• Echo<br />
• Talk<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 8<br />
Shiow-yang Wu Note 4
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Designing <strong>UDP</strong>-based Protocols<br />
• Use simple request-reply model<br />
• Each request should fit into a single <strong>UDP</strong><br />
packet (data < 508 bytes = 576-60-8, where<br />
576 is the minimum packet size that should<br />
be handled by all IP networks, specified in<br />
RFC791).<br />
• Keep the state machines small<br />
• Provide loss handling through retransmission<br />
on one side only (client or server)<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 9<br />
Java <strong>UDP</strong> <strong>Programming</strong><br />
• Two main classes:<br />
• java.net.DatagramPacket<br />
• java.net.DatagramSocket<br />
• No differentiation between client and server<br />
sockets. Every datagram socket can be used<br />
both for sending and receiving datagrams<br />
• DatagramPacket instances contain<br />
destination or source address and a message.<br />
Can only be used with DatagramSocket.<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 10<br />
Shiow-yang Wu Note 5
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Java <strong>UDP</strong> <strong>Programming</strong><br />
Java client<br />
program<br />
5.Create<br />
DatagramPacket<br />
(“server”,4567,data)<br />
Java server<br />
program<br />
2.Create<br />
DatagramPacket<br />
(data buffer)<br />
4.Create<br />
(any)<br />
java.net.<br />
Datagram.<br />
Packet<br />
1.Create<br />
(4567)<br />
java.net.<br />
Datagram.<br />
Packet<br />
java.net.<br />
DatagramSocket<br />
6.send<br />
(datagram)<br />
CSIE33000 Network <strong>Programming</strong><br />
7.Create <strong>UDP</strong> header;<br />
send as IP packet<br />
java.net.<br />
DatagramSocket<br />
3.receivei<br />
(datagram)<br />
8.Write<br />
sender<br />
host/port+<br />
data<br />
<strong>UDP</strong> <strong>Programming</strong> 11<br />
java.net.DatagramPacket<br />
• Store the header and data content of a <strong>UDP</strong><br />
datagram<br />
• Three main attributes<br />
• IP address<br />
• <strong>UDP</strong> port<br />
• payload data stored in a byte-array<br />
• When used for transmission, the IP and port<br />
are the destination; when used for receiving,<br />
they are source IP and port.<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 12<br />
Shiow-yang Wu Note 6
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
DatagramPacket Constructors<br />
• DatagramPacket(bute[] buf, int length)<br />
max buf length<br />
• DatagramPacket(bute[] buf, int offset, int length)<br />
// use indeces [offset .. offset+length-1]<br />
// used in appending the data received<br />
• DatagramPacket(bute[] buf, int length, InetAddress<br />
address, int port)<br />
// destination/source address and port<br />
• DatagramPacket(bute[] buf, int offset, int length,<br />
InetAddress address, int port)<br />
• All above throw IllegalArgumentException<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 13<br />
Creating a <strong>UDP</strong> packet<br />
// to receive data from a remote machine<br />
DatagramPacket packet =<br />
new DatagramPacket(new byte[256], 256);<br />
// to send data to a remote machine<br />
DatagramPacket packet =<br />
new DatagramPacket( new byte[128], 128,<br />
address, port );<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 14<br />
Shiow-yang Wu Note 7
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
DatagramPacket Methods (1)<br />
• Get destination/source address and port<br />
• InetAddress getAddress()<br />
• int getPort()<br />
• Access packet payload<br />
• byte[] getData()<br />
• int getOffset()<br />
• int getLength() // returns the actual length received<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 15<br />
DatagramPacket Write Methods<br />
• To change destination address and port<br />
• void setAddress(InetAddress address)<br />
• void setPort(int port)<br />
• To change the data buffer<br />
• void setData(byte[] buf)<br />
• void setData(bute[] buf, int offset, in length)<br />
// use the specified portion of the buf as payload<br />
• Note that change the buffer does not<br />
automatically change the max buffer size. A<br />
setLength() must be made if this is desired.<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 16<br />
Shiow-yang Wu Note 8
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
java.net.DatagramSocket<br />
• The same socket class can serve both as<br />
client and server datagram sockets.<br />
• Unlike stream sockets, datagram sockets do<br />
not have a protocol peer.<br />
• The same socket instance can be used to<br />
send/receive datagrams to/from any<br />
host/port destination/source<br />
i CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 17<br />
Creating <strong>UDP</strong> sockets<br />
• A <strong>UDP</strong> socket can be used both for reading<br />
and writing packets.<br />
• Write operations are asynchronous; however,<br />
read operations are blocking.<br />
• Since there is no guaranteed delivery, a<br />
single-threaded application could stall.<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 18<br />
Shiow-yang Wu Note 9
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
DatagramSocket Constructors<br />
• DatagramSocket() throws SocketException,<br />
SecurityException<br />
// use an arbitrary available <strong>UDP</strong> port<br />
• DatagramSocket(int port) throws SocketException,<br />
SecurityException<br />
• DatagramSocket(int port, InetAddress address)<br />
throws SocketException, SecurityException<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 19<br />
Creating <strong>UDP</strong> Sockets<br />
// A client datagram socket:<br />
DatagramSocket clientSocket =<br />
new DatagramSocket();<br />
// A server datagram socket:<br />
DatagramSocket serverSocket =<br />
new DatagramSocket(port);<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 20<br />
Shiow-yang Wu Note 10
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
DatagramSocket Operations<br />
• To send a datagram<br />
• void send(DatagramPacket packet) throws<br />
IOException, SecurityException,<br />
IllegalArgumentException;<br />
• To receive a datagram<br />
• void receive(DatagramPacket packet) throws<br />
IOException, SecurityException;<br />
• Note: if the received datagram is larger than the<br />
packet buffer, it is truncated.<br />
• void close()<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 21<br />
Sending <strong>UDP</strong> Packets<br />
// create datagram packet<br />
. . .<br />
// create datagram client socket<br />
. . .<br />
boolean finished = false;<br />
while ( ! finished ) {<br />
// write data to packet buffer<br />
clientSocket.send(packet);<br />
// see if there is more to send<br />
}<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 22<br />
Shiow-yang Wu Note 11
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Listening for <strong>UDP</strong> Packets<br />
// create datagram packet<br />
. . .<br />
// create datagram server socket<br />
. . .<br />
boolean finished = false;<br />
while ( ! finished ) {<br />
serverSocket.receive(packet);<br />
// process the packet<br />
}<br />
serverSocket.close();<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 23<br />
DatagramSocket Methods<br />
• Get the port and net interface the socket is<br />
associated with<br />
• int getLocalPort()<br />
• InetAddress getLocalAddress()<br />
• To restrict the packets to a single destination<br />
• void connect(InetAddress address, int port) throws<br />
SecurityException, IllegalArgumentException<br />
• void disconnect()<br />
• To get the restricted address and port<br />
• InetAddress getInetAddress() // null if not restricted<br />
• int getPort() // -1 if not restricted<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 24<br />
Shiow-yang Wu Note 12
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
• Timeout<br />
DatagramSocket Configuration<br />
• void setSoTimeout(int timeout) throws SocketException<br />
• int getSoTimeout()<br />
• Buffer size management<br />
• void setSendBufferSize(int size) throws SocketException<br />
• int getSendBufferSize() throws SocketException<br />
• void setReceiveBufferSize(int size) throws<br />
SocketException<br />
ti<br />
• int getReceiveBufferSize() throws SocketException<br />
• Size management methods only affect performance.<br />
They will not cause datagram truncation.<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 25<br />
Non-blocking I/O receiving<br />
<strong>UDP</strong> packets<br />
• You can set a time-out in milliseconds to<br />
determine how long a read operation blocks,<br />
before throwing an exception.<br />
• socket.setSoTimeout(duration);<br />
• If the duration given in milliseconds is<br />
exceeded, an exception is thrown:<br />
• java.io.InterruptedException<br />
i<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 26<br />
Shiow-yang Wu Note 13
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Simple<strong>UDP</strong>Example.java (1)<br />
import java.net.*;<br />
// Simple example that sends and receives a <strong>UDP</strong> datagram */<br />
public class Simple<strong>UDP</strong>Example {<br />
public static void main(String[] main)<br />
throws UnknownHostException, SocketException,<br />
java.io.IOException {<br />
int port = 5264; // hard-coded for simplicity<br />
// create datagram socket<br />
DatagramSocket socket = new DatagramSocket(port);<br />
socket.setSoTimeout(5000);<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 27<br />
Simple<strong>UDP</strong>Example.java (2)<br />
// create datagram payload + set destination to self<br />
String outMessage = "Hello <strong>UDP</strong> world!";<br />
byte[] data = outMessage.getBytes();<br />
DatagramPacket packet =<br />
new DatagramPacket(data, data.length,<br />
InetAddress.getByName("localhost"), port);<br />
// send datagram (to ourself)<br />
System.out.println("Sending message: " +<br />
outMessage);<br />
socket.send(packet);<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 28<br />
Shiow-yang Wu Note 14
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Simple<strong>UDP</strong>Example.java (3)<br />
// prepare to receive datagram: because we reuse the<br />
// DatagramPacket instance we must reset its length even<br />
// though we replace its data buffer!<br />
packet.setData(new byte[512]);<br />
packet.setLength(512);<br />
// receive datagram (may time out)<br />
System.out.println("Waiting t tl iti for datagram ...");<br />
socket.receive(packet);<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 29<br />
Simple<strong>UDP</strong>Example.java (4)<br />
// print result<br />
String inMessage = new String(packet.getData(),<br />
0, packet.getLength());<br />
System.out.println("Received message: " +<br />
inMessage);<br />
socket.close();<br />
}<br />
}<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 30<br />
Shiow-yang Wu Note 15
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Processing <strong>UDP</strong> Packets<br />
ByteArrayInputStream bin =<br />
new ByteArrayInputStream(<br />
packet.getData() );<br />
DataInputStream din =<br />
new DataInputStream(bin);<br />
// read the contents of the packet<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 31<br />
Sending <strong>UDP</strong> packets<br />
• When you receive a packet, the ip and port<br />
number of the sender are set in the<br />
DatagramPacket.<br />
• You can use the same packet to reply, by<br />
overwriting the data, using the method:<br />
• packet.setData(newbuffer);<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 32<br />
Shiow-yang Wu Note 16
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
9 Steps for <strong>UDP</strong> Server<br />
1. Create a DatagramSocket object<br />
DatagramSocket datagramSocket =<br />
new DatagramSocket(1234);<br />
2. Create a buffer for incoming datagram<br />
byte[] buffer = new byte[256];<br />
3. Create a DatagramPacket object for the<br />
incoming datagrams<br />
DatagramPacket inPacket =<br />
new DatagramPacket(buffer, buffer.length);<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 33<br />
9 Steps for <strong>UDP</strong> Server (2)<br />
4. Accept an incoming datagram.<br />
datagramSocket.receive(inPacket);<br />
5. Accept the sender's address and port from the<br />
packet.<br />
InetAddress clientAddress =<br />
inPacket.getAddress();<br />
int clientPort = inPacket.getPort();<br />
6. Retrieve the data from the buffer.<br />
String message = new String(<br />
inPacket.getData(),<br />
0, inPacket.getLength());<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 34<br />
Shiow-yang Wu Note 17
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
9 Steps for <strong>UDP</strong> Server (3)<br />
7. Create the response datagram.<br />
DatagramPacket outPacket = new<br />
DatagramPacket(response.getBytes(),<br />
response.length(),clientAddress,<br />
clientPort); // response is a String<br />
8. Send the response datagram. (4~8 may be<br />
executed indefinitely)<br />
datagramSocket.send(outPacket);<br />
9. Close the DatagramSocket.<br />
datagramSocket.close();<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 35<br />
<strong>UDP</strong>EchoServer.java<br />
import java.io.*;<br />
import java.net.*;<br />
public class <strong>UDP</strong>EchoServer<br />
{<br />
private static final int PORT = 1234;<br />
private static DatagramSocket amSocket datagramSocket;<br />
amSocket<br />
private static DatagramPacket inPacket, outPacket;<br />
private static byte[] buffer;<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 36<br />
Shiow-yang Wu Note 18
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
<strong>UDP</strong>EchoServer.java (2)<br />
public static void main(String[] args) {<br />
System.out.println("Opening port...\n");<br />
try { //Step 1.<br />
datagramSocket = new DatagramSocket(PORT);<br />
}<br />
catch(SocketException sockEx) {<br />
System.out.println("Unable to attach to port!");<br />
System.exit(1);<br />
}<br />
handleClient();<br />
}<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 37<br />
<strong>UDP</strong>EchoServer.java (3)<br />
private static void handleClient() {<br />
try {<br />
String messageIn,messageOut;<br />
int numMessages = 0;<br />
do {<br />
buffer = new byte[256]; //Step 2.<br />
inPacket = new DatagramPacket(<br />
buffer, buffer.length); //Step 3.<br />
datagramSocket.receive(inPacket); //Step 4.<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 38<br />
Shiow-yang Wu Note 19
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
<strong>UDP</strong>EchoServer.java (4)<br />
InetAddress clientAddress =<br />
inPacket.getAddress(); //Step 5.<br />
int clientPort = inPacket.getPort(); //Step 5.<br />
messageIn = new String( inPacket.getData(), 0,<br />
inPacket.getLength() ); //Step 6.<br />
System.out.println("Message received.");<br />
numMessages++;<br />
messageOut = "Message " + numMessages<br />
+ ": " + messageIn;<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 39<br />
<strong>UDP</strong>EchoServer.java (5)<br />
}<br />
outPacket = new DatagramPacket(<br />
messageOut.getBytes(),<br />
g messageOut.length(),<br />
clientAddress,<br />
clientPort); //Step 7.<br />
//Step 8.<br />
datagramSocket.send(outPacket);<br />
} while (true);<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 40<br />
Shiow-yang Wu Note 20
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
}<br />
}<br />
<strong>UDP</strong>EchoServer.java (6)<br />
catch(IOException ioEx) {<br />
ioEx.printStackTrace();<br />
}<br />
finally //If exception, close connection.<br />
{<br />
System.out.println("\n* Closing connection... *");<br />
datagramSocket.close(); close(); //Step 9.<br />
}<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 41<br />
8 Steps for <strong>UDP</strong> Client<br />
1. Create a DatagramSocket object.<br />
DatagramSocket datagramSocket =<br />
new DatagramSocket();<br />
2. Create the outgoing datagram.<br />
DatagramPacket outPacket = new<br />
DatagramPacket(message.getBytes(),<br />
message.length(), host, PORT);<br />
3. Send the datagram message.<br />
datagramSocket.send(outPacket);<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 42<br />
Shiow-yang Wu Note 21
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
8 Steps for <strong>UDP</strong> Client (2)<br />
4. Create a buffer for incoming datagrams.<br />
byte[] buffer = new byte[256];<br />
5. Create a DatagramPacket object for the<br />
incoming datagrams.<br />
DatagramPacket inPacket = new<br />
DatagramPacket(buffer,<br />
buffer.length);<br />
6. Accept an incoming datagram.<br />
datagramSocket.receive(inPacket);<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 43<br />
8 Steps for <strong>UDP</strong> Client (3)<br />
7. Retrieve the data from the buffer.<br />
String response = new<br />
String(inPacket.getData(),0,<br />
inPacket.getLength());<br />
8. Close the DatagramSocket.<br />
datagramSocket.close();<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 44<br />
Shiow-yang Wu Note 22
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
<strong>UDP</strong>EchoClient.java<br />
import java.io.*;<br />
import java.net.*;<br />
import java.util.*;<br />
public class <strong>UDP</strong>EchoClient<br />
{<br />
private static InetAddress host;<br />
private static ti final int PORT = 1234;<br />
private static DatagramSocket datagramSocket;<br />
private static DatagramPacket inPacket, outPacket;<br />
private static byte[] buffer;<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 45<br />
<strong>UDP</strong>EchoClient.java (2)<br />
public static void main(String[] args) {<br />
try {<br />
host = InetAddress.getLocalHost();<br />
}<br />
catch(UnknownHostException uhEx) {<br />
System.out.println("Host ID not found!");<br />
System.exit(1); exit(1);<br />
}<br />
accessServer();<br />
}<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 46<br />
Shiow-yang Wu Note 23
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
<strong>UDP</strong>EchoClient.java (3)<br />
private static void accessServer() {<br />
try {<br />
//Step 1.<br />
datagramSocket = new DatagramSocket();<br />
//Set up stream for keyboard entry...<br />
Scanner userEntry = new Scanner(System.in);<br />
String message="", response="";<br />
do {<br />
System.out.print("Enter message: ");<br />
message = userEntry.nextLine();<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 47<br />
<strong>UDP</strong>EchoClient.java (4)<br />
if (!message.equals("***CLOSE***")) {<br />
outPacket = new DatagramPacket(<br />
message.getBytes(), getBytes()<br />
message.length(),<br />
host,PORT); //Step 2.<br />
datagramSocket.send(outPacket); //Step 3.<br />
buffer = new byte[256]; //Step 4.<br />
inPacket = new DatagramPacket(<br />
buffer, buffer.length); //Step 5.<br />
datagramSocket.receive(inPacket); //Step 6.<br />
response = new String(inPacket.getData(),<br />
0, inPacket.getLength());//Step 7.<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 48<br />
Shiow-yang Wu Note 24
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
}<br />
}<br />
<strong>UDP</strong>EchoClient.java (5)<br />
System.out.println("\nSERVER> " + response);<br />
}<br />
} while (!message.equals( equals("***CLOSE***"));<br />
}<br />
catch(IOException ioEx) {<br />
ioEx.printStackTrace();<br />
}<br />
finally {<br />
System.out.println("\n* t tl *Closing connection... *");<br />
datagramSocket.close(); //Step 8.<br />
}<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 49<br />
Execution of <strong>UDP</strong>EchoServer<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 50<br />
Shiow-yang Wu Note 25
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Execution of <strong>UDP</strong>EchoClient<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 51<br />
<strong>UDP</strong> Echo Service<br />
• The Echo protocol (RFC862) is an old<br />
Internet standard.<br />
• The server receive datagrams on port 7 and<br />
send the same data back.<br />
1. <strong>UDP</strong> datagram to port 7,<br />
with arbitrary data<br />
Client<br />
2. <strong>UDP</strong> datagram to originating<br />
port, with same data<br />
Echo Server<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 52<br />
Shiow-yang Wu Note 26
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Echo<strong>UDP</strong>Client.java (1)<br />
import java.net.*;<br />
import java.io.*;<br />
// Static methods for the RFC 862 <strong>UDP</strong> echo protocol client */<br />
public class Echo<strong>UDP</strong>Client {<br />
// Standard <strong>UDP</strong> echo service port (port=7)<br />
public static final int STANDARD_ECHO_PORT = 7;<br />
// Default number of tries to receive an echo response<br />
public static final int DEFAULT_TRIES = 3;<br />
/** Default polling expiration in milliseconds */<br />
public static final int DEFAULT_EXPIRE_MILLIS = 2000;<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 53<br />
Echo<strong>UDP</strong>Client.java (2)<br />
// Maximum <strong>UDP</strong> payload size to be sent or received<br />
public static final int MAX_<strong>UDP</strong>_BUFFER_SIZE = 508;<br />
// Counter used to generate unique Echo requests<br />
protected static int nextRequestID= 0;<br />
// Prevent instantiation (only static methods offerred)<br />
private Echo<strong>UDP</strong>Client() {<br />
}<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 54<br />
Shiow-yang Wu Note 27
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Echo<strong>UDP</strong>Client.java (3)<br />
/** Returns true if the host is running a <strong>UDP</strong> echo service in<br />
the specified port number and successfully returned an<br />
exact copy of a test message transmitted. <br />
The service is polled up to tries times, with<br />
pollMillis in between polls.<br />
@param address - the <strong>UDP</strong> echo service address<br />
@param port - the <strong>UDP</strong> echo service port<br />
@param a tries - number of echo tries before e failure<br />
@param pollMillis - number of milliseconds for poll expiration<br />
@exception IOException - if the socket could not be created<br />
@exception SecurityException - if the security manager did<br />
not permit the network operations<br />
CSIE33000 */ Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 55<br />
Echo<strong>UDP</strong>Client.java (4)<br />
public static boolean echo(InetAddress address, int port,<br />
int tries, int pollExpireMillis)<br />
throws IOException, SecurityException {<br />
if (address == null)<br />
throw new NullPointerException("null server address");<br />
// Generate a unique request ID<br />
long outValue;<br />
synchronized(Echo<strong>UDP</strong>Client.class) {<br />
outValue = nextRequestID;<br />
nextRequestID++;<br />
}<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 56<br />
Shiow-yang Wu Note 28
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Echo<strong>UDP</strong>Client.java (5)<br />
// Create request payload (write current time to byte array)<br />
ByteArrayOutputStream byteOut = new<br />
ByteArrayOutputStream();<br />
DataOutputStream dataOut = new<br />
DataOutputStream(byteOut);<br />
try {<br />
dataOut.writeLong(outValue);<br />
dataOut.close();<br />
} catch (IOException e) {<br />
throw new RuntimeException("Unexpected I/O exception:"<br />
+ e);<br />
}<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 57<br />
Echo<strong>UDP</strong>Client.java (6)<br />
// Create datagram packet out of request<br />
DatagramPacket outPacket =<br />
new DatagramPacket(byteOut.toByteArray(),<br />
byteOut.size(), address, port);<br />
DatagramPacket inPacket = new DatagramPacket<br />
(new byte[MAX_<strong>UDP</strong>_BUFFER_SIZE],<br />
MAX_<strong>UDP</strong>_BUFFER_SIZE);<br />
// Create and configure socket<br />
DatagramSocket socket = new DatagramSocket();<br />
socket.setSoTimeout(pollExpireMillis);<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 58<br />
Shiow-yang Wu Note 29
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Echo<strong>UDP</strong>Client.java (7)<br />
try {<br />
// Loop "tries" times sending the <strong>UDP</strong> packet.<br />
for(int i=0; i
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Echo<strong>UDP</strong>Client.java (9)<br />
// We're looping back so reset the inPacket buffer length<br />
// (must do so every time we reuse a DatagramPacket<br />
// instance for a DatagramSocket.receive() invocation)<br />
inPacket.setLength(MAX_<strong>UDP</strong>_BUFFER_SIZE);<br />
} // for (each try)<br />
} finally {<br />
try { socket.close(); } catch (Throwable e) { }<br />
}<br />
return(false);<br />
} // echo()<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 61<br />
Echo<strong>UDP</strong>Client.java (10)<br />
// Command-line utility for performing <strong>UDP</strong> echo requests.<br />
public static void main(String[] args) {<br />
if ( (args.length == 0) || (args.length > 2) ) {<br />
System.err.println("Usage: Echo<strong>UDP</strong>Client {}");<br />
System.exit(1);<br />
}<br />
InetAddress address = null;<br />
try {<br />
address = InetAddress.getByName(args[0]);<br />
} catch (UnknownHostException e) {<br />
System.err.println("Echo<strong>UDP</strong>Client: unknown host " + args[0]);<br />
System.exit(1);<br />
}<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 62<br />
Shiow-yang Wu Note 31
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Echo<strong>UDP</strong>Client.java (11)<br />
int port = STANDARD_ECHO_PORT;<br />
if (args.length > 1) {<br />
try {<br />
port = Integer.parseInt(args[1]);<br />
} catch (NumberFormatException e) {<br />
System.err.println("Echo<strong>UDP</strong>Client: invalid port number " + args[1]);<br />
System.exit(1);<br />
}<br />
}<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 63<br />
Echo<strong>UDP</strong>Client.java (12)<br />
try {<br />
if (echo(address, port,<br />
DEFAULT_TRIES, DEFAULT_EXPIRE_MILLIS)) {<br />
System.out.println("Echo service active on " + address);<br />
} else {<br />
System.out.println("No echo reply from " + address);<br />
}<br />
System.exit(0); exit(0);<br />
} catch (Throwable e) {<br />
System.err.println("Echo<strong>UDP</strong>Client: " + e);<br />
System.exit(1);<br />
} } } // Echo<strong>UDP</strong>Client<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 64<br />
Shiow-yang Wu Note 32
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Echo<strong>UDP</strong>Server.java (1)<br />
import java.net.*;<br />
import java.io.*;<br />
// Server implementing the RFC 862 <strong>UDP</strong> echo protocol<br />
public class Echo<strong>UDP</strong>Server extends Thread {<br />
// Standard <strong>UDP</strong> echo service port in RFC 862 (port=7)<br />
public static int STANDARD_ECHO_PORT = 7;<br />
// Default no. of milliseconds between termination checks<br />
public static int DEFAULT_TERMINATION_CHECK_MILLIS TERMINATION MILLIS = 5000;<br />
// The maximum <strong>UDP</strong> data length possible (in bytes)<br />
public static int MAX_<strong>UDP</strong>_DATA_LENGTH = 65508;<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 65<br />
Echo<strong>UDP</strong>Server.java (2)<br />
/** <strong>UDP</strong> socket used to receive echo requests */<br />
protected DatagramSocket socket;<br />
/** Controls execution of the datagram receive thread */<br />
protected boolean isActive;<br />
/** Constructs an RFC 862 <strong>UDP</strong> Echo Protocol server<br />
* @param port - the <strong>UDP</strong> port number used for binding<br />
* @exception SocketException - if the socket creation fails<br />
* @exception SecurityException - if permission refused<br />
*/<br />
public Echo<strong>UDP</strong>Server(int port) throws SocketException {<br />
super("EchoServer(" + port + ")");<br />
socket = new DatagramSocket(port);<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 66<br />
Shiow-yang Wu Note 33
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Echo<strong>UDP</strong>Server.java (3)<br />
socket.setSoTimeout(DEFAULT_TERMINATION_CHECK_MILLIS);<br />
isActive = true;<br />
start();<br />
}<br />
// Requests asynchronous termination of the receiving thread<br />
public void terminate() {<br />
isActive = false;<br />
}<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 67<br />
Echo<strong>UDP</strong>Server.java (4)<br />
/** Main thread receives and sends back any data received.<br />
* <br />
* Loop termination controlled by the terminate() method.<br />
*/<br />
public void run() {<br />
System.out.println("Echo server bound to port " +<br />
socket.getLocalPort());<br />
DatagramPacket receivePacket =<br />
new DatagramPacket(<br />
new byte[MAX_<strong>UDP</strong>_DATA_LENGTH],<br />
MAX_<strong>UDP</strong>_DATA_LENGTH);<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 68<br />
Shiow-yang Wu Note 34
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Echo<strong>UDP</strong>Server.java (5)<br />
while(isActive) {<br />
try {<br />
// Reset the receivePacket length to the byte array length<br />
receivePacket.setLength(MAX_<strong>UDP</strong>_DATA_LENGTH);<br />
// Wait to receive echo request (may also time-out)<br />
socket.receive(receivePacket);<br />
// We just send the packet back to the sender<br />
socket.send(receivePacket);<br />
} catch (InterruptedIOException e) {<br />
// ignore (used to check for termination)<br />
} catch (Throwable e) {<br />
// ignore<br />
}<br />
}<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 69<br />
Echo<strong>UDP</strong>Server.java (6)<br />
try { socket.close(); } catch (Throwable e) { }<br />
}<br />
/** Command-line utility for performing <strong>UDP</strong> echo requests. */<br />
public static void main(String[] args) {<br />
if (args.length > 1) {<br />
System.err.println("Usage: Echo<strong>UDP</strong>Server { }");<br />
System.exit(1);<br />
}<br />
int port = STANDARD_ECHO_PORT;<br />
if (args.length == 1) {<br />
try {<br />
port = Integer.parseInt(args[0]);<br />
} catch (NumberFormatException e) {<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 70<br />
Shiow-yang Wu Note 35
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Echo<strong>UDP</strong>Server.java (7)<br />
System.err.println("Echo<strong>UDP</strong>Server: invalid port number " +<br />
args[0]);<br />
System.exit(1);<br />
}<br />
}<br />
try {<br />
Echo<strong>UDP</strong>Server server = new Echo<strong>UDP</strong>Server(port);<br />
server.join();<br />
} catch (Throwable e) {<br />
System.err.println("Echo<strong>UDP</strong>Server: " + e);<br />
System.exit(1);<br />
}<br />
}<br />
}<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 71<br />
Typical <strong>UDP</strong> client code<br />
• Create <strong>UDP</strong> socket to contact server (with a<br />
given hostname and service port number)<br />
• Create <strong>UDP</strong> packet.<br />
• Call send(packet), sending request to the<br />
server.<br />
• Possibly call receive(packet) (if we need a<br />
reply).<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 72<br />
Shiow-yang Wu Note 36
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Typical <strong>UDP</strong> Server code<br />
• Create <strong>UDP</strong> socket listening to a well known<br />
port number.<br />
• Create <strong>UDP</strong> packet buffer<br />
• Call receive(packet) to get a request,<br />
noting the address of the client.<br />
• Process request and send reply back with<br />
send(packet).<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 73<br />
Debugging<br />
• Debugging <strong>UDP</strong> can be difficult.<br />
• Write routines to print out addresses.<br />
• Use a debugger.<br />
• Include code that can handle unexpected<br />
situations.<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 74<br />
Shiow-yang Wu Note 37
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Asynchronous Errors<br />
• What happens if a client sends data to a<br />
server that is not running?<br />
• ICMP “port unreachable” error is generated by<br />
receiving host and send to sending host.<br />
• The ICMP error may reach the sending host after<br />
send() has already returned!<br />
• The next call dealing with the socket could return<br />
the error.<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 75<br />
Assignment 2<br />
1. Modify the TCP and <strong>UDP</strong> Echo examples discussed<br />
in the class such that the server and client are<br />
running on different machines.<br />
2. Write a TCPcalculatorServer.java program that<br />
accepts client request for arithmetic calculation in<br />
prefix form (eg. “+ 3 8”) and returns the result in<br />
the response. Write a TCPcalculatorClient.java<br />
program that interactively accepts user’s calculation<br />
command, sends to the server, receives the<br />
response, and print the result.<br />
CSIE33000 Network <strong>Programming</strong><br />
<strong>UDP</strong> <strong>Programming</strong> 76<br />
Shiow-yang Wu Note 38
CSIE33000 Network <strong>Programming</strong><br />
<strong>Lecture</strong><strong>06</strong> <strong>UDP</strong> <strong>Programming</strong><br />
Assignment 2 (cont.)<br />
3. Write a <strong>UDP</strong>messageServer.java program that provides<br />
on-line messaging service by accepting client requests of<br />
the form “send mboxID message” or “receive mboxID”<br />
which are to send(receive) a message to(from) the<br />
designated mailbox. You are free to assume that each<br />
part of the request is in a separate line. Write the<br />
corresponding client program to test the service. Note<br />
that you may need to save the messages before they are<br />
received. Once a message is received, it can be deleted<br />
from the server.<br />
• Due Date: Oct 30, 2008<br />
CSIE33000 Network <strong>Programming</strong> <strong>UDP</strong> <strong>Programming</strong> 77<br />
Shiow-yang Wu Note 39