Build Chat Application using Java

We will be learning about socket programming and will also create a simple console based chat application in Java using learned concepts.

ยท

6 min read

Build Chat Application using Java

Introduction

Socket programming is an essential concept in network communications, enabling devices to connect and share data over a network. By using sockets, you can build robust applications that communicate efficiently, whether on a local network or over the internet. In this blog, we will dive into the world of socket programming and guide you through creating a simple yet functional console based chat application. This step-by-step tutorial will cover the basics of socket programming, setting up a server and client, and communication with client and server.

What is Socket Programming?

Socket programming is a way to enable communication between two or more devices over a network. This communication is established using sockets, which are endpoints for sending and receiving data. Sockets can be used in various types of network communication, such as between a client and server, or between peers in a peer-to-peer network.

The Client-Server Model

Socket programming typically follows the client-server model:

  • Server: Listens for incoming connections on a specific port and waits for clients to connect. It can also handle multiple client connections, usually by creating a new thread or using asynchronous I/O for each client.

  • Client: Initiates a connection to the server, sends requests, and receives responses. The client must know the server's IP address and port number.

Key Components

  • IP Address: Identifies a device on a network.

  • Port Number: Identifies a specific process or service on a device.

  • Socket: Combines an IP address and a port number to create a unique endpoint for communication.

Use Cases of Socket Programming

Socket programming is used in various applications, such as:

  • Web Servers: Handling requests from web browsers.

  • Chat Applications: Enabling real-time text, voice, or video communication.

  • File Transfer Protocols: Transferring files between devices.

  • Game Development: Facilitating multiplayer gaming.

By understanding these fundamental concepts, you guys now have a solid foundation and are ready to create a chat application using Java sockets. So Lets start building one!

Step 1 : Setting up development environment :

  • Prerequisites: Java 8 or above, IDE like IntelliJ IDEA or Eclipse.

Step 2 : Creating our Server:

First we will be creating a server socket by passing port number to it, to which client can send connection request to start communication. Once the connection is established, we will be reading the messages send by client and writing to the client using console.

Let us create our Server with name Server.Java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
public class Server {

    ServerSocket serverSocket;
    Socket socket;
    BufferedReader bufferedReader;
    PrintWriter out;

    public Server(){
        try {
            serverSocket = new ServerSocket(8887);
            System.out.println("Server is ready to accept new requests....");
            socket = serverSocket.accept();
            // get input stream from socket (client) convert bytes into chars using InputStreamReader and assign it to BUfferedReader
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream());
        }
        catch (Exception e){
           e.printStackTrace();
        }
    }

      public static void main(String[] args) {
        System.out.println("Server is starting....");
        new Server();
    }
}

In above code, we are setting up a server socket to accept client connections on port 8887 and handling input/output streams.

serverSocket.accept(): This method call waits for a client to connect. When a client connects, the method returns a Socket object that represents the connection to the client.

bufferedReader: This is a BufferedReader object used to read text from the input stream of the client.

out: This is a PrintWriter object used to send text to the client.

We have done basic setup of our server. Now let us adding reading and writing logic through which our server will be able to read clients messages and also will be able to reply to them.

We will be adding 2 methods :

1) startReading() : This method will read the messages that client is sending until the connection is not closed and will simultaneously print those on console.

2) startWriting() : This method will take message from user/server and send it to client.

And we will be calling these 2 methods from our constructor after initializing our BufferedReader and PrintWriter.

Lets write startReading method :

 private void startReading() {
        Runnable input = () -> {
            System.out.println("Server Reader started....");
            try {
            while(true && !socket.isClosed()){

                    String messageFromClient = bufferedReader.readLine();
                    if(messageFromClient.equalsIgnoreCase("Bye")){
                        System.out.println("Client has ended the chat!");
                        socket.close();
                        break;
                    }
                    System.out.println("Client:"+messageFromClient);
            }
            } catch (IOException e) {
                System.out.println("Connection with client is closed!!");
            }
        };
        new Thread(input).start();
    }
  • The startReading method creates a new thread by using Runnable and starts it so that it continuously reads messages from a client.

  • When a message is received, it is printed to the console.

  • If the client sends "Bye", the server acknowledges it as client has ended the chat, closes the connection, and exits the loop.

  • If any IOException is caught, a message indicating the connection is closed is printed.

Lets write startWriting method :

   private void startWriting() {
        Runnable output = () -> {
            System.out.println("Server Writer started....");
          while (true && !socket.isClosed()){
              try {
                  BufferedReader serverToClient = new BufferedReader(new InputStreamReader(System.in));
                  String content = serverToClient.readLine();
                  out.println(content);
                  out.flush();
                  if(content.equalsIgnoreCase("bye")){
                      socket.close();
                      break;
                  }
              } catch (IOException e) {
                  System.out.println("Connection with client is closed!!");
              }
          }
        };
        new Thread(output).start();
    }
  • The startWriting method creates a new thread by using Runnable and starts it so that it continually reads messages from the console and sends them to the client.

  • When a message is entered, it is sent to the client using PrintWriter.

  • If the user types "bye", the server closes the connection and exits the loop.

  • If any IOException is caught, a message indicating the connection is closed is printed.

Together with the startReading method, this setup allows for full-duplex communication between the server and the client, where messages can be read from and written to the client simultaneously.

Now we are ready with our Server. Similarly we will also have to create our Client. Only difference in our Client class will be that, instead of creating a server socket we will have to establish a connection with our server using the IP address of server and port number on which our server is listening.

Sample code for the same will be as follows :

  public Client(){
        try {
            System.out.println("Sending connection request to server...");
            socket = new Socket("127.0.0.1",8887);
            System.out.println("Connected with Server!! Start chatting..");
            // get input stream from socket (server) convert bytes into chars using InputStreamReader and assign it to BUfferedReader
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream());
            }
          catch (Exception e){
            e.printStackTrace();
        }
    }
  • The socket = new Socket("127.0.0.1", 8887); line creates a client socket and connects it to a server running on the local machine (localhost) (127.0.0.1) on port 8887.

  • This socket can then be used for network communication between the client and the server.

To run the application, first compile both the Server.java and Client.java classes using javac command and using console, run Server.java first and then Client.java.

Note : Until you do not run the Client, server will stay in waiting state.

And start communicating......!!!

Conclusion

In this tutorial, we've taken a comprehensive journey through the basics of socket programming in Java by building a simple chat application. We started with an introduction to socket programming and its importance in enabling network communication. We then set up our development environment, created a server and client, and enhanced our application to establish communication between client and server.

For those interested in further extending the application, you can try adding GUI to the same instead if reading and writing from console.

Thanks for reading....Keep Coding, Keep exploring!!

For Complete source code of above chat application (along with GUI) click here.

ย