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 :

  • To send a message from any client, type the message, followed by a “#” and then the name of the recipient client. Please note that this implementation gives names as “client 0”, “client 1″….”client n” and so carefully names must be appended int the end. After that press Enter key.
  • Once a message is sent, the handler for this client will receive the message and it will be delivered to the specified client.
  • If any client sends a message to this client, the readMessage thread will automatically print the message on the console.
  • Once a client is done with chatting, he can send a “logout” message without any recipient name so that server would know that this client has logged off the system. It is recommended to send a logout message before closing the terminal for the client to avoid any errors.

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-

  • Create a graphical user interface for clients for sending and receiving messages. A tool such as Netbeans can be used to quickly design an interface
  • Currently the names are hard-coded as client 0, client 1. This can be improved to use user given nicknames.
  • This implementation can be further enhanced to provide client the list of current active users so that he can know who all of his friends are online. A simple method can be implemented for this purpose which when invoked prints the names in active list.

This article is contributed by Rishabh Mahrsee. 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 write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up


Article Tags :
Practice Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.