Open In App

Creating an Asynchronous Multithreaded chat Application in Java

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report


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.


Last Updated : 12 Sep, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads