Creating an Asynchronous Multithreaded chat Application in Java


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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();
    }
}

chevron_right


UnsyncChatClient.java

filter_none

edit
close

play_arrow

link
brightness_4
code

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();
    }
}

chevron_right


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.


My Personal Notes arrow_drop_up


If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.