Skip to content

🚀 “Create a Real-Time Chat Application in Java (No External Libraries!)”

🧠 What You’ll Learn:

In this tutorial, we’re going to build a simple Java-based chat application from scratch using Java Sockets and Swing for the client interface. This tutorial will cover:

  • Socket programming: Learn how Java’s ServerSocket and Socket classes allow clients and servers to communicate.
  • Multi-threading: Handle multiple clients at once with threads.
  • Real-time messaging: Send messages from one client to another in real time.
  • GUI with Swing: Build a sleek chat interface with Java Swing, no external libraries needed!

This tutorial assumes you have a basic understanding of Java programming and want to dive deeper into networking and multi-threading.


🛠️ Project Overview:

FeatureTech Used
Networking (Sockets)Java ServerSocket and Socket
Multi-threadingJava Thread
GUI (Optional)Java Swing (for UI)
Message ExchangeText-based chat (Client-Server)

📁 File Structure:

We’ll keep the project simple with two main files:

  • Server.java: Handles the server-side logic for accepting and broadcasting messages.
  • Client.java: A simple client interface to connect to the server and send/receive messages.

🧾 Full Source Code:

Server.java (Server-side logic)

import java.io.*;
import java.net.*;
import java.util.*;

public class Server {
    private static final int PORT = 12345;
    private static final List<PrintWriter> clients = new ArrayList<>();

    public static void main(String[] args) {
        System.out.println("Server is running...");
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            while (true) {
                new ClientHandler(serverSocket.accept()).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static class ClientHandler extends Thread {
        private final Socket socket;
        private final PrintWriter out;
        private final BufferedReader in;

        public ClientHandler(Socket socket) {
            this.socket = socket;
            try {
                this.out = new PrintWriter(socket.getOutputStream(), true);
                this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            } catch (IOException e) {
                throw new RuntimeException("Error in creating streams", e);
            }
        }

        @Override
        public void run() {
            synchronized (clients) {
                clients.add(out);
            }
            try {
                String message;
                while ((message = in.readLine()) != null) {
                    System.out.println("Received: " + message);
                    synchronized (clients) {
                        for (PrintWriter writer : clients) {
                            writer.println(message);
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                synchronized (clients) {
                    clients.remove(out);
                }
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Client.java (Client-side interface)

import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Client {
    private static final String SERVER_ADDRESS = "localhost";
    private static final int SERVER_PORT = 12345;
    private PrintWriter out;
    private BufferedReader in;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(Client::new);
    }

    public Client() {
        JFrame frame = new JFrame("Chat Client");
        frame.setSize(400, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JTextArea textArea = new JTextArea();
        textArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(textArea);
        frame.add(scrollPane, BorderLayout.CENTER);

        JTextField inputField = new JTextField();
        frame.add(inputField, BorderLayout.SOUTH);

        inputField.addActionListener(e -> {
            String message = inputField.getText();
            inputField.setText("");
            out.println(message);
        });

        frame.setVisible(true);

        try (Socket socket = new Socket(SERVER_ADDRESS, SERVER_PORT)) {
            out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            String message;
            while ((message = in.readLine()) != null) {
                textArea.append(message + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

🧠 Code Breakdown (Line-by-Line)

Server Code Breakdown

  1. ServerSocket serverSocket = new ServerSocket(PORT);
    • This line initializes the server, making it listen for incoming connections on port 12345.
  2. new ClientHandler(serverSocket.accept()).start();
    • The server waits for a client connection using serverSocket.accept(). Once a client connects, a new ClientHandler thread is created to handle the connection.
  3. clients.add(out);
    • The PrintWriter associated with the client is added to a list of active clients. This allows the server to broadcast messages to all connected clients.
  4. while ((message = in.readLine()) != null)
    • The server listens for incoming messages from clients. If a message is received, it’s broadcast to all connected clients.
  5. synchronized (clients)
    • Synchronization ensures that only one thread can modify the clients list at a time, preventing race conditions.
  6. clients.remove(out);
    • When a client disconnects, their PrintWriter is removed from the list of clients.

Client Code Breakdown

  1. JFrame frame = new JFrame("Chat Client");
    • A new Swing JFrame is created, which will contain the chat window.
  2. JTextArea textArea = new JTextArea();
    • A JTextArea is used to display the chat history. It’s set to non-editable so that users can only type messages in the input field.
  3. inputField.addActionListener(e -> { ... });
    • An ActionListener is added to the input field. When the user presses Enter, the input is sent to the server.
  4. out.println(message);
    • The message typed by the user is sent to the server using the PrintWriter connected to the server.
  5. textArea.append(message + "\n");
    • Messages received from the server are appended to the JTextArea, displaying them in the chat window.

🧪 How to Run the Application:

  1. Start the server by running the Server.java file

javac Server.java
java Server

2. Start the client by running the Client.java file:

javac Client.java
java Client

3. Multiple clients: Run the Client class on different terminals or machines to simulate a multi-user chat environment.

💡 Bonus Features to Implement:

  • Private Messaging: Add a feature where users can send private messages to each other by typing a username.
  • Message History: Save the chat history to a file and load it when a user connects.
  • User Authentication: Implement a simple authentication system to identify users before they can send messages.

✍️ Final Thoughts:

Creating a Java chat application with sockets is a fantastic way to learn networking and multi-threading in Java. This tutorial provided a solid foundation on how to implement real-time communication in a simple way, without any external dependencies. You can take this project further by adding features like private messaging, user authentication, and more!

Building this chat app helps you grasp the concepts of client-server communication, multi-threading, and real-time updates, all of which are fundamental in network programming.

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *