Prerequisite: Datagrams in Java
In this article, we will learn how to use Datagrams in Java to create an Asynchronous messaging application in java. Asynchronous in this context means that both the server and the client can send each other texts independently without waiting for any kind of response from the other party. We will be using the concept of multi-threading to implement Sending and receiving text messages between the processes with the help of DatagramPackets. Datagrams are bundles of information passed between applications. Once the datagram has been released to its intended target, it is independent and there is no assurance that it will arrive or even that some application will be there to receive it. Java implements datagrams on top of the UDP (User Datagram Protocol) protocol.
Below is the implementation of the above approach.
UnsyncChatServer.java
import java.net.*; import java.io.*; import java.util.*; public class UnSyncChatServer { public static void main(String args[]) throws IOException, InterruptedException { // Create DatagramSocket and get ip DatagramSocket ss = new DatagramSocket( 1234 ); InetAddress ip = InetAddress.getLocalHost(); System.out.println( "Running UnSyncChatServer.java" ); System.out.println( "Server is Up...." ); // Create a sender thread // with a nested runnable class definition Thread ssend; ssend = new Thread( new Runnable() { @Override public void run() { try { Scanner sc = new Scanner(System.in); while ( true ) { synchronized ( this ) { byte [] sd = new byte [ 1000 ]; // scan new message to send sd = sc.nextLine().getBytes(); DatagramPacket sp = new DatagramPacket( sd, sd.length, ip, 5334 ); // send the new packet ss.send(sp); String msg = new String(sd); System.out.println( "Server says: " + msg); // exit condition if ((msg).equals( "bye" )) { System.out.println( "Server" + " exiting... " ); break ; } System.out.println( "Waiting for" + " client response... " ); } } } catch (Exception e) { System.out.println( "Exception occured" ); } } }); Thread sreceive; sreceive = new Thread( new Runnable() { @Override public void run() { try { while ( true ) { synchronized ( this ) { byte [] rd = new byte [ 1000 ]; // Receive new message DatagramPacket sp1 = new DatagramPacket( rd, rd.length); ss.receive(sp1); // Convert byte data to string String msg = ( new String(rd)).trim(); System.out.println( "Client (" + sp1.getPort() + "):" + " " + msg); // Exit condition if (msg.equals( "bye" )) { System.out.println( "Client" + " connection closed." ); break ; } } } } catch (Exception e) { System.out.println( "Exception occured" ); } } }); ssend.start(); sreceive.start(); ssend.join(); sreceive.join(); } } |
UnsyncChatClient.java
import java.io.*; import java.net.*; import java.util.Scanner; public class UnSyncChatClient { public static void main(String args[]) throws IOException, InterruptedException { // create DatagramSocket and get ip DatagramSocket cs = new DatagramSocket( 5334 ); InetAddress ip = InetAddress.getLocalHost(); System.out.println( "Running UnSyncChatClient.java" ); System.out.println( "Client is Up...." ); // create a sender thread with a nested // runnable class definition Thread csend; csend = new Thread( new Runnable() { @Override public void run() { try { Scanner sc = new Scanner(System.in); while ( true ) { synchronized ( this ) { byte [] sd = new byte [ 1000 ]; // scan new message to send sd = sc.nextLine().getBytes(); // create datagram packet // for new message DatagramPacket sp = new DatagramPacket( sd, sd.length, ip, 1234 ); // send the new packet cs.send(sp); String msg = new String(sd); System.out.println( "Client says: " + msg); // exit condition if (msg.equals( "bye" )) { System.out.println( "client " + "exiting... " ); break ; } System.out.println( "Waiting for " + "server response..." ); } } } catch (IOException e) { System.out.println( "Exception occured" ); } } }); // create a receiver thread with a nested // runnable class definition Thread creceive; creceive = new Thread( new Runnable() { @Override public void run() { try { while ( true ) { synchronized ( this ) { byte [] rd = new byte [ 1000 ]; // receive new message DatagramPacket sp1 = new DatagramPacket( rd, rd.length); cs.receive(sp1); // convert byte data to string String msg = ( new String(rd)).trim(); System.out.println( "Server: " + msg); // exit condition if (msg.equals( "bye" )) { System.out.println( "Server" + " Stopped...." ); break ; } } } } catch (IOException e) { System.out.println( "Exception occured" ); } } }); csend.start(); creceive.start(); csend.join(); creceive.join(); } } |
Output: Window 1 (UnSyncChatServer.java)
Running UnSyncChatServer.java Server is Up.... Client (5334): hey hi Server says: hi Waiting for client response... ssup? Server says: ssup? Waiting for client response... Client (5334): good Client (5334): u? good as well Server says: good as well Waiting for client response... Client (5334): bye Client connection closed. bye Server says: bye Server exiting...
Output: Window 2 (UnSyncChatClient.java)
Running UnSyncChatClient.java Client is Up.... hey Client says: hey Waiting for server response... Server: hi Server: ssup? good Client says: good Waiting for server response... u? Client says: u? Waiting for server response... Server: good as well bye Client says: bye client exiting... Server: bye Server Stopped...
Note:
- Use an offline IDE to run this program as an online IDE may timeout.
- Run program 1 first and the program 2.