Open In App

Multi-threaded Chat Application in Java | Set 2 (Client Side Programming)

Prerequisites : Introducing threads in socket programming, Multi-threaded chat Application | Set 1

This article gives the implementation of client program for the multi-threaded chat application. Till now all examples in socket programming assume that client first sends some information and then server or other clients responds to that information.
In real world, this might not be the case. It is not required to send someone a message in order to be able to receive one. A client should readily receive a message whenever it is delivered to it i.e sending and receiving must be implemented as separate activities rather than sequential.
There is a very simple solution which uses threads to achieve this functionality. In the client side implementation we will be creating two threads:



  1. SendMessage : This thread will be used for sending the message to other clients. The working is very simple, it takes input the message to send and the recipient to deliver to. Note that this implementation assumes the message to be of the format message # recipient, where recipient is the name of the recipient. It then writes the message on its output stream which is connected to the handler for this client. The handler breaks the message and recipient part and deliver to particular recipient. Lets look at how this thread can be implemented.




    Thread sendMessage = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
      
                        // read the message to deliver.
                        String msg = sc.nextLine();
                        try {
      
                            // write on the output stream
                            dos.writeUTF(msg);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
    
    
  2. readMessage : A similar approach is taken for creating a thread for receiving the messages. When any client tries to write on this clients input stream, we use readUTF() method to read that message. The following snippet of how this thread is implemented is shown below-




    Thread readMessage = new Thread(new Runnable() {
      
                @Override
                public void run() {
      
                    while (true) {
                        try {
      
                            // read the message sent to this client
                            String msg = dis.readUTF();
                            System.out.println(msg);
                        } catch (IOException e) {
      
                            e.printStackTrace();
                        }
                    }
                }
            });
    
    

The remaining steps of client side programming are similar to previous examples. A brief explanation is as follows –

  1. Establish a Socket Connection
  2. Communication
    Communication occurs with the help of the readMessage and sendMessage threads. Separate threads for reading and writing ensures simultaneous sending and receiving of messages.




// Java implementation for multithreaded chat client
// Save file as Client.java
  
import java.io.*;
import java.net.*;
import java.util.Scanner;
  
public class Client 
{
    final static int ServerPort = 1234;
  
    public static void main(String args[]) throws UnknownHostException, IOException 
    {
        Scanner scn = new Scanner(System.in);
          
        // getting localhost ip
        InetAddress ip = InetAddress.getByName("localhost");
          
        // establish the connection
        Socket s = new Socket(ip, ServerPort);
          
        // obtaining input and out streams
        DataInputStream dis = new DataInputStream(s.getInputStream());
        DataOutputStream dos = new DataOutputStream(s.getOutputStream());
  
        // sendMessage thread
        Thread sendMessage = new Thread(new Runnable() 
        {
            @Override
            public void run() {
                while (true) {
  
                    // read the message to deliver.
                    String msg = scn.nextLine();
                      
                    try {
                        // write on the output stream
                        dos.writeUTF(msg);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
          
        // readMessage thread
        Thread readMessage = new Thread(new Runnable() 
        {
            @Override
            public void run() {
  
                while (true) {
                    try {
                        // read the message sent to this client
                        String msg = dis.readUTF();
                        System.out.println(msg);
                    } catch (IOException e) {
  
                        e.printStackTrace();
                    }
                }
            }
        });
  
        sendMessage.start();
        readMessage.start();
  
    }
}

Output :
From client 0 :



hello#client 1
client 1 : heya
how are you#client 1
client 1 : fine..how about you
logout

From client 1 :

client 0 : hello
heya#client 0
client 0 : how are you
fine..how about you#client 0
logout

Important points :

How to run the above program ?

Similar to previous examples, first run the server and then run multiple instances of the client. From each of the client, try sending message to each other. Please make sure you send message to only a valid client, i.e. to the client available on active list.

Suggested Improvements

This was only the explanation part as to how threads and socket programming can be used to create powerful programs. There are some suggested improvements to above implementations for the interested readers-


Article Tags :