A Network Programming Lecture by Steven Choy
Lecture Overview: Introduction datagram networking - Connection-oriented vs connectionless networking - Using classes DatagramPacket and DatagramSocket - Datagram applications
Datagram Networking
Connection-oriented networking
- Based on TCP, using streams
- Establish connection before transmitting
- Guarantee correct data in correct order
- More transmission overhead
Connectionless networking
- Also called datagram networking
- Based on UDP (User Datagram Protocol), using datagrams/packets
- No guarantee on data arrival nor order
- But can achieve better transmission rate
Uses of datagram networking
Why use UDP rather than TCP?
- Timely transmission of data is required, and data reliability is not essential
- Real-time applications, e.g. streaming audio and video
- Quality degradation is more acceptable than delays
- Multicast applications
- Communication using small and independent packets
- Simple query operations, e.g. domain-name lookups, time server queries, network analysis
Programming UDP (vs TCP)
- UDP uses
DatagramSocket to send & receive data
- There is no server socket
- The coding difference between UDP clients and servers are not as clear as in the case of TCP
- UDP communicates with independent packets
- There is no stream involved
- UDP socket is not dedicated to a single remote host
- We use same UDP socket to send packets to different destinations & receive packets from different sources
Using Class DatagramPacket
- Represent a UDP packet
- Maximum size of 65507 bytes (theoretical!)
- 65535 - 20 (for IP header) - 8 (for UDP header)
- Some OS/implementation impose smaller limits
- In sender side, it stores data to be transmitted
- Specify IP address & port of destination
- Be kind! Don't use maximum size, e.g. 65000 bytes
- In receiver side, act as buffer to receive data
- Retrieve IP address & port of source
- Prepare for the worst! Use max size, i.e. 65507 bytes
- Constructors
// receive
DatagramPacket(byte buffer[], int length)
// transmit & receive
DatagramPacket(byte buffer[], int length, InetAddress address, int port)
InetAddress getAddress()
int getPort()
byte[] getData()
int getLength()
void setAddress(InetAddress address)
void setPort(int port)
void setData(byte[] buffer)
void setLength(int length)
DatagramPacket(byte[] buffer, int length)
creates a datagram packet with the specified buffer and length; it is typically used for receiving packets.
DatagramPacket(byte[] buffer, int length, InetAddress address, int port)
creates a datagram packet with the specified buffer, length, remote host and port number; it is typically used for sending packets.
InetAddress getAddress(), void setAddress(InetAddress addr)
gets or sets the remote IP address of a datagram packet; the remote IP address is the destination address on sending packets or the source address on receiving packets.
int getPort(), void setPort(int port)
gets or sets the remote port number in the datagram packet; the remote port number refers to the destination host on sending packets or the source host on receiving packets.
byte[] getData(), void setData(byte[] buf)
gets or sets the buffer for the sending data or receiving data in the datagram packet.
int getLength(), void setLength(int length)
gets or sets the length of the sending data or receiving data in the datagram packet.
Using Class DatagramSocket
- To send and receive
DatagramPacket
- A single
DatagramSocket can be used for both sending & receiving
- Listen to a UDP port to receive packets
- Valid ports 0-65535, 1-1023 reserved
- Constructors
// transmit
DatagramSocket() throws SocketException;
// receive & transmit
DatagramSocket(int port) throws SocketException;
DatagramSocket(int port, InetAddress local) throws SocketException;
void send(DatagramPacket packet) throws IOException
void receive(DatagramPacket packet) throws IOException
InetAddress getLocalAddress()
setSoTimeout, getSoTimeout, setSendBufferSize, getSendBufferSize, setReceiveBufferSize, getReceiveBufferSize, connect, disconnect, getInetAddress, getPort
DatagramSocket()
creates a datagram socket and binds it to an available port on the local machine; it is typically used for sending packets.
DatagramSocket(int port)
creates a datagram socket and binds it to the specified port on the local machine; it is typically used for receiving and possibly sending packets.
void send(DatagramPacket packet)
sends the specified datagram packet, which contains the destination IP address and port number, data to be sent and its length.
void receive(DatagramPacket packet)
Receives a datagram and puts it data to the specified datagram packet, setting the source IP address and port number, data received and its length in the packet parameter.
InetAddress getLocalAddress(), int getLocalPort()
returns the address or port number on the local machine.
void close()
closes this datagram socket.
isClosed()
tests whether the socket is closed.
Sending and Receiving UDP Packet
Program to receive a packet
- 1. Create a
DatagramSocket
- 2. Create a
DatagramPacket to hold UDP datagram once received
- 3. Call
receive() of DatagramSocket to wait for a UDP datagram to be received
- 4. The received data, sender's address and port number in the
DatagramPacket can be extracted by DatagramPacket's methods
- 5. Close the
DatagramSocket. This stops further reception of UDP packets
DatagramSocket socket = new DatagramSocket (port);
byte buffer[] = new byte[65508];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive (packet);
InetAddress fromAddress = packet.getAddress ();
int fromPort = packet.getPort ();
int length = packet.getLength ();
byte[] data = packet.getData ();
socket.close();
Program to send a packet
- 1. Create a
DatagramSocket. If you don't care about the local port number to be used, let's the operating system assign one for you
- 2. Create a
DatagramPacket object and specify data, recipient's address and port number
- 3. Call
send() method of DatagramSocket to place the UDP packet into the network for delivery to the recipient. Note that the local address and port number are automatically transmitted as part of the UDP header
- 4. Close the DatagramSocket
DatagramSocket socket = new DatagramSocket ();
DatagramPacket packet = new DatagramPacket
(data, data.length, InetAddress.getByName("www.ouhk.edu.hk"), 1782);
socket.send (packet);
socket.close();
A UDP echo server
import java.net.*;
import java.io.*;
public class UDPEchoServer {
protected int port;
public UDPEchoServer (int port) {
this.port = port;
}
public static void main (String[] args) throws IOException {
if (args.length != 1) throw
new IllegalArgumentException("Syntax: UDPEchoServer <port>");
UDPEchoServer server = new UDPEchoServer (Integer.parseInt (args[0]));
server.execute ();
}
public void execute () throws IOException {
DatagramSocket socket = new DatagramSocket (port);
while (true) {
System.out.println("Waiting to receive packets");
byte buffer[] = new byte[65508];
DatagramPacket packet = new DatagramPacket (buffer, buffer.length);
socket.receive (packet);
System.out.print("* A packet is received and is echoed back to: ");
System.out.println(packet.getAddress()+":"+packet.getPort());
DatagramPacket response = new DatagramPacket( packet.getData(),
packet.getLength(), packet.getAddress(), packet.getPort() );
socket.send (response);
}
}
}
A UDP echo client
import java.net.*;
import java.io.*;
public class UDPEchoClient {
protected DatagramSocket socket;
protected DatagramPacket packet;
public void execute (String host, int port, String message) throws IOException {
socket = new DatagramSocket ();
buildPacket (message, host, port);
socket.send (packet);
receivePacket ();
socket.close ();
}
protected void buildPacket (String message, String host, int port)
throws IOException {
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream ();
DataOutputStream dataOut = new DataOutputStream (byteArrayOut);
dataOut.writeUTF (message);
byte[] data = byteArrayOut.toByteArray ();
packet = new DatagramPacket
(data, data.length,InetAddress.getByName (host), port);
}
protected void receivePacket () throws IOException {
byte buffer[] = new byte[65508];
DatagramPacket packet = new DatagramPacket (buffer, buffer.length);
socket.receive (packet);
ByteArrayInputStream byteArrayIn =
new ByteArrayInputStream(packet.getData(), 0, packet.getLength());
DataInputStream dataIn = new DataInputStream (byteArrayIn);
String result = dataIn.readUTF ();
System.out.println ("Received: " + result + ".");
}
public static void main (String[] args) throws IOException {
if (args.length != 3) throw new IllegalArgumentException
("Syntax: UDPEchoClient <host> <port> <message>");
UDPEchoClient client = new UDPEchoClient();
client.execute(args[0], Integer.parseInt (args[1]), args[2]);
}
}
Simple Datagram Applications
A daytime server & client
- Daytime Protocol - RFC 867
- Server
- Listen on UDP port 13
public static final int DEFAULT_PORT = 13;
- Reply current date and time in ASCII
new java.util.Date().toString().getBytes("latin1");
- Client
- Send a packet with no content to server
new DatagramPacket(new byte[256], 1, host, port);
- Receive response from server
DNS over UDP
- DNS can use UDP on UDP port 53
- Or TCP on server TCP port 53 (TCP port ≠ UDP port)
Class Quiz
- 1) Which constructor is commonly used in creating a DatagramPacket object used to receive UDP packets?
- 2) Which constructor is commonly used in creating a DatagramPacket object used to send UDP packets?
- 3) List the four methods that DatagramPacket can obtain information on the UDP packet that has received.
- 4) List the four methods for setting the DatagramPacket properties for transmission.
- 5) What is the function of the method setSoTimeout(int timeout)?
- 6) What are the methods for obtaining the IP address and port number of the machine on which a DatagramSocket is created?
- 7) What happens if you create a DatagramSocket without specifying a port number?
- 8) Is it possible to use a single DatagramSocket for both sending and receiving purposes?
Extra materials for probing further
From the Java Tutorials > Custom Networking > All About Datagrams.
From School of Computing, Napier University, Edinburgh
Thanks for Reading
If you would rather like to have this lecture note in printed format, please click the print action link in the top right corner.
If you find any problem in this lecture note, please feel free to tell Steven via steven@findaway.hk.