Skip to content

AnuragBanerjee-agbe/ChatApp.java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 

Repository files navigation

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

public class ChatApp { private static final int PORT = 12345;

public static void main(String[] args) throws IOException {
    Scanner sc = new Scanner(System.in);
    System.out.println("START AS (1) SERVER OR (2) CLIENT?");
    int choice = sc.nextInt();
    sc.nextLine();

    if (choice == 1) {
        new Thread(() -> {
            try {
                startServer();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    } else if (choice == 2) {
        startClient();
    } else {
        System.out.println("INVALID CHOICE.");
    }
}

// ===== SERVER CODE =====
private static Set<ClientHandler> clientsList = Collections.synchronizedSet(new HashSet<>());

public static void startServer() throws IOException {
    ServerSocket serverSocket = new ServerSocket(PORT);
    System.out.println("SERVER STARTED ON PORT " + PORT);

    while (true) {
        Socket socket = serverSocket.accept();
        ClientHandler handler = new ClientHandler(socket);
        clientsList.add(handler);
        new Thread(handler).start();
    }
}

static void broadcast(String message, ClientHandler exclude) {
    synchronized (clientsList) {
        for (ClientHandler client : clientsList) {
            if (client != exclude) {
                client.sendMessage(message);
            }
        }
    }
}

static void sendPrivateMessage(String targetUser, String message, ClientHandler sender) {
    boolean found = false;
    synchronized (clientsList) {
        for (ClientHandler client : clientsList) {
            if (client.name.equalsIgnoreCase(targetUser)) {
                client.sendMessage("[PRIVATE] " + sender.name + ": " + message);
                found = true;
                break;
            }
        }
    }
    if (!found) {
        sender.sendMessage("User '" + targetUser + "' not found.");
    }
}

static void removeClient(ClientHandler ch) {
    clientsList.remove(ch);
}

static class ClientHandler implements Runnable {
    private Socket socket;
    private BufferedReader br;
    private BufferedWriter bw;
    String name;

    public ClientHandler(Socket socket) {
        this.socket = socket;
        try {
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        } catch (IOException e) {
            closeAll();
        }
    }

    @Override
    public void run() {
        try {
            bw.write("Enter your name: ");
            bw.flush();
            name = br.readLine().trim();

            System.out.println((name + " CONNECTED.").toUpperCase());
            broadcast(name + " joined the chat.", this);

            bw.write("Welcome " + name + "! Type /users to see who's online. Type /msg username message to send private message.\n");
            bw.flush();

            String msg;
            while ((msg = br.readLine()) != null) {
                if (msg.equalsIgnoreCase("exit")) break;

                if (msg.equalsIgnoreCase("/users")) {
                    sendUserList();
                } else if (msg.startsWith("/msg ")) {
                    String[] parts = msg.split(" ", 3);
                    if (parts.length >= 3) {
                        String target = parts[1];
                        String privateMsg = parts[2];
                        sendPrivateMessage(target, privateMsg, this);
                    } else {
                        sendMessage("Invalid format. Use /msg username message");
                    }
                } else {
                    String fullMsg = getTimestamp() + " " + name + ": " + msg;
                    System.out.println(fullMsg.toUpperCase());
                    broadcast(fullMsg, this);
                }
            }
        } catch (IOException e) {
            System.out.println((name + " DISCONNECTED.").toUpperCase());
        } finally {
            closeAll();
            removeClient(this);
            broadcast(name + " left the chat.", this);
        }
    }

    public void sendMessage(String msg) {
        try {
            bw.write(msg);
            bw.newLine();
            bw.flush();
        } catch (IOException e) {
            closeAll();
        }
    }

    public void sendUserList() {
        StringBuilder sb = new StringBuilder("Online users:\n");
        synchronized (clientsList) {
            for (ClientHandler client : clientsList) {
                sb.append("• ").append(client.name).append("\n");
            }
        }
        sendMessage(sb.toString());
    }

    private String getTimestamp() {
        return "[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]";
    }

    private void closeAll() {
        try {
            if (br != null) br.close();
            if (bw != null) bw.close();
            if (socket != null) socket.close();
        } catch (IOException e) {
            // ignore silently
        }
    }
}

// ===== CLIENT CODE =====
public static void startClient() {
    try (Scanner scanner = new Scanner(System.in)) {
        Socket socket = new Socket("localhost", PORT);
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

        // Listener thread for incoming messages
        new Thread(() -> {
            try {
                String msg;
                while ((msg = br.readLine()) != null) {
                    System.out.println(msg);
                }
            } catch (IOException e) {
                // silent close
            }
        }).start();

        // Send user messages to server
        while (true) {
            String input = scanner.nextLine();
            bw.write(input);
            bw.newLine();
            bw.flush();

            if (input.equalsIgnoreCase("exit")) {
                socket.close();
                break;
            }
        }

    } catch (IOException e) {
        System.out.println("CLIENT ERROR: " + e.getMessage().toUpperCase());
    }
}

}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published