Computer networks -- 2008-2009 -- info.uvt.ro/Sockets/UDP/Examples/PingPong

From Wikiversity

Quick links: front; agenda; courses 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13; examination.

Important! Please note that the current work serves mainly as general guidance and discussion topics, and is by no means the reference material for the course. For further information please consult the dedicated section.

Client[edit]

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;


public class PingPongClient
{
	public static void main (String[] arguments)
	{
		if (arguments.length != 2) {
			System.err.println ("wrong arguments !!!");
			return;
		}
		
		// Selecting the arguments.
		String serverAddressAsString = arguments[0];
		String serverPortAsString = arguments[1];
		
		// Resolving the server address.
		InetAddress serverAddress;
		try {
			serverAddress = InetAddress.getByName (serverAddressAsString);
		} catch (UnknownHostException exception) {
			System.err.println ("wrong server name !!!");
			return;
		}
		
		// Parsing the server port.
		int serverPort;
		try {
			serverPort = Integer.parseInt (serverPortAsString);
		} catch (NumberFormatException exception) {
			System.err.println ("wrong server port !!!");
			return;
		}
		
		// ---------------------
		// Ping request sending.
		// ---------------------
		
		// Creating the ping message.
		String message = "ping";
		
		// Creating and binding the socket.
		DatagramSocket socket;
		try {
			System.err.println ("creating and binding socket...");
			socket = new DatagramSocket ();
		} catch (SocketException exception) {
			// An unknown / unexpected network error was encountered. (Not a normal situation.)
			exception.printStackTrace (System.err);
			return;
		}
		
		// Only for debugging purposes.
		// Obtaining and printing the local socket address (the datagram source). (Which should be an instance of InetSocketAddress.)
		InetSocketAddress localSocketAddress = (InetSocketAddress) socket.getLocalSocketAddress ();
		System.err.println ("local socket address -->");
		printInetSocketAddress (localSocketAddress);
		
		// Creating the datagram destination (that is the server socket address).
		InetSocketAddress datagramDestination = new InetSocketAddress (serverAddress, serverPort);
		
		// Only for debugging purposes.
		// Printing the datagram destination address.
		System.err.println ("datagram destination -->");
		printInetSocketAddress (datagramDestination);
		
		// Creating the datagram backing buffer.
		byte[] datagramBuffer = message.getBytes ();
		int datagramBufferOffset = 0;
		int datagramBufferSize = datagramBuffer.length;
		
		// Creating the datagram.
		DatagramPacket datagram;
		try {
			System.err.println ("creating datagram...");
			datagram = new DatagramPacket (datagramBuffer, datagramBufferOffset, datagramBufferSize, datagramDestination);
		} catch (SocketException exception) {
			// An unknown / unexpected network error was encountered. (Not a normal situation.)
			exception.printStackTrace (System.err);
			return;
		}
		
		// Sending the datagram.
		try {
			System.err.println ("sending datagram...");
			socket.send (datagram);
		} catch (IOException exception) {
			// The datagram could not be sent. (Maybe destination is unreachable.)
			exception.printStackTrace (System.err);
			return;
		}
		
		// ----------
		// This is the pong reply receiving.
		// ----------
		
		// Set a maximum datagram backing buffer size.
		datagramBufferSize = 2048;
		
		// Create the datagram backing buffer.
		datagramBuffer = new byte [datagramBufferSize];
		datagramBufferOffset = 0;
		
		// Re-create the datagram.
		datagram = new DatagramPacket (datagramBuffer, datagramBufferOffset, datagramBufferSize);
		
		// Receiving the datagram.
		try {
			System.err.println ("receiving datagram...");
			socket.receive (datagram);
		} catch (IOException exception) {
			// An unknown / unexpected network error was encountered. (Not a normal situation.)
			exception.printStackTrace (System.err);
			return;
		}
		
		// Obtaining the datagram source address. (Which should be an instance of InetSocketAddress.)
		InetSocketAddress datagramSource = (InetSocketAddress) datagram.getSocketAddress ();
		
		// Only for debugging purposes.
		// Printing the datagram source address.
		System.err.println ("datagram source -->");
		printInetSocketAddress (datagramSource);
		
		// Obtaining the datagram actual length (how much data was received, or how much of the backing buffer was used).
		int datagramBufferUsed = datagram.getLength ();
		
		// Decoding the message (which should be a string).
		message = new String (datagramBuffer, datagramBufferOffset, datagramBufferUsed);
		
		System.err.println ("received -->");
		System.err.println ("    message = " + message);
		
		// ----------
		
		// Closing the socket.
		System.err.println ("closing socket...");
		socket.close ();
	}
	
	public static void printInetSocketAddress (InetSocketAddress socketAddress)
	{
		// Obtaining the local IP address.
		InetAddress address = socketAddress.getAddress ();
		
		// Obtaining the local port.
		int port = socketAddress.getPort ();
		
		// Printing obtained information;
		printInetAddress (address);
		System.err.println ("    port = " + port);
	}
	
	public static void printInetAddress (InetAddress address)
	{
		// Obtaining the IP as a string.
		String ipAsString = address.getHostAddress ();
		
		// Obtaining the IP as an array of bytes.
		byte[] ipAsBytes = address.getAddress ();
		
		// Obtaining the reverse host name.
		String reverseName = address.getCanonicalHostName ();
		
		// Printing the default string representation.
		System.err.println ("    address = " + address);
		
		// Printing the IP as string.
		System.err.println ("    ip as string = " + ipAsString);
		
		// Printing the IP as bytes.
		System.err.println ("    ip as bytes length = " + ipAsBytes.length);
		System.err.print ("    ip as bytes =");
		for (byte b : ipAsBytes)
			System.err.print (" " + (b));
		System.err.println ();
		
		// Printing the reverse host name.
		System.err.println ("    reverse name = " + reverseName);
	}
}

Server[edit]

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;


public class PingPongServer
{
	public static void main (String[] arguments)
	{
		if (arguments.length != 1) {
			System.err.println ("wrong arguments !!!");
			return;
		}
		
		// Selecting the arguments.
		String serverPortAsString = arguments[0];
		
		// Parsing the server port.
		int serverPort;
		try {
			serverPort = Integer.parseInt (serverPortAsString);
		} catch (NumberFormatException exception) {
			System.err.println ("wrong server port !!!");
			return;
		}
		
		// Creating and binding the socket.
		DatagramSocket socket;
		try {
			System.err.println ("creating and binding socket...");
			socket = new DatagramSocket (serverPort);
		} catch (SocketException exception) {
			// The socket can not be created or bound. (Maybe the port is already in use.)
			exception.printStackTrace (System.err);
			return;
		}
		
		// Only for debugging purposes.
		// Obtaining and printing the local socket address (the datagram destination). (Which should be an instance of InetSocketAddress.)
		InetSocketAddress localSocketAddress = (InetSocketAddress) socket.getLocalSocketAddress ();
		System.err.println ("local socket address -->");
		printInetSocketAddress (localSocketAddress);
		
		// ----------
		// This is the ping receiving part.
		// ----------
		
		// Set a maximum request datagram backing buffer size.
		int requestDatagramBufferSize = 2048;
		
		// Create the request datagram backing buffer.
		byte[] requestDatagramBuffer = new byte [requestDatagramBufferSize];
		int requestDatagramBufferOffset = 0;
		
		// Create the request datagram. (We can reuse the same datagram for all requests.)
		DatagramPacket requestDatagram = new DatagramPacket (requestDatagramBuffer, requestDatagramBufferOffset, requestDatagramBufferSize);
		
		// Set a maximum message counter.
		int counter = 10;
		
		// Wait for new datagrams.
		while (counter > 0) {
			
			// Receiving the request datagram.
			try {
				System.err.println ("receiving request datagram...");
				socket.receive (requestDatagram);
			} catch (IOException exception) {
				// An unknown / unexpected network error was encountered. (Not a normal situation.)
				exception.printStackTrace (System.err);
				return;
			}
			
			// Obtaining the request datagram source address. (Which should be an instance of InetSocketAddress.)
			InetSocketAddress requestDatagramSource = (InetSocketAddress) requestDatagram.getSocketAddress ();
			
			// Only for debugging purposes.
			// Printing the request datagram source address.
			System.err.println ("request datagram source -->");
			printInetSocketAddress (requestDatagramSource);
			
			// Obtaining the datagram actual length (how much data was received, or how much of the backing buffer was used).
			int requestDatagramBufferUsed = requestDatagram.getLength ();
			
			// Decoding the message (which should be a string).
			String requestMessage = new String (requestDatagramBuffer, requestDatagramBufferOffset, requestDatagramBufferUsed);
			
			System.err.println ("received -->");
			System.err.println ("    request message = " + requestMessage);
			
			// ----------
			// This is the pong sending part.
			// ----------
			
			// Creating the reply message.
			String replyMessage = "pong";
			
			// Creating the reply datagram backing buffer.
			byte[] replyDatagramBuffer = replyMessage.getBytes ();
			int replyDatagramBufferOffset = 0;
			int replyDatagramBufferSize = replyDatagramBuffer.length;
			
			// Setting the reply datagram destination address.
			InetSocketAddress replyDatagramDestination = requestDatagramSource;
			
			// Creating the reply datagram.
			DatagramPacket replyDatagram;
			try {
				System.err.println ("creating reply datagram...");
				replyDatagram = new DatagramPacket (replyDatagramBuffer, replyDatagramBufferOffset, replyDatagramBufferSize, replyDatagramDestination);
			} catch (SocketException exception) {
				// An unknown / unexpected network error was encountered. (Not a normal situation.)
				exception.printStackTrace (System.err);
				return;
			}
			
			// Sending the reply datagram.
			try {
				System.err.println ("sending reply datagram...");
				socket.send (replyDatagram);
			} catch (IOException exception) {
				// The datagram could not be sent. (Maybe destination is unreachable.)
				exception.printStackTrace (System.err);
			}
			
			counter--;
		}
		
		// Closing the socket.
		System.err.println ("closing socket...");
		socket.close ();
	}
	
	public static void printInetSocketAddress (InetSocketAddress socketAddress)
	{
		// Obtaining the local IP address.
		InetAddress address = socketAddress.getAddress ();
		
		// Obtaining the local port.
		int port = socketAddress.getPort ();
		
		// Printing obtained information;
		printInetAddress (address);
		System.err.println ("    port = " + port);
	}
	
	public static void printInetAddress (InetAddress address)
	{
		// Obtaining the IP as a string.
		String ipAsString = address.getHostAddress ();
		
		// Obtaining the IP as an array of bytes.
		byte[] ipAsBytes = address.getAddress ();
		
		// Obtaining the reverse host name.
		String reverseName = address.getCanonicalHostName ();
		
		// Printing the default string representation.
		System.err.println ("    address = " + address);
		
		// Printing the IP as string.
		System.err.println ("    ip as string = " + ipAsString);
		
		// Printing the IP as bytes.
		System.err.println ("    ip as bytes length = " + ipAsBytes.length);
		System.err.print ("    ip as bytes =");
		for (byte b : ipAsBytes)
			System.err.print (" " + (b));
		System.err.println ();
		
		// Printing the reverse host name.
		System.err.println ("    reverse name = " + reverseName);
	}
}