diff --git a/src/main/java/com/university/chat/Client/ServerListener.java b/src/main/java/com/university/chat/Client/ServerListener.java index b609d74..f3ecda0 100644 --- a/src/main/java/com/university/chat/Client/ServerListener.java +++ b/src/main/java/com/university/chat/Client/ServerListener.java @@ -1,18 +1,66 @@ package com.university.chat.Client; +import com.university.chat.Common.ChatMessage; +import com.university.chat.Common.FileMessage; + +import java.io.ObjectInputStream; + public class ServerListener implements Runnable{ - // TODO: store the ObjectInputStream from the user socket + // store the ObjectInputStream from the user socket // (this should be the same input stream the // chatClient created when connecting) + private final ObjectInputStream in; + public ServerListener(ObjectInputStream in) + { + this.in = in; + } @Override public void run() { try { - // TODO: In an infinite loop read objects from the server + // In an infinite loop read objects from the server // - if it's a ChatMessage -> print ": " // - if it's a FileMessage -> print that a file was received // (filename + sender), it's already // saved to disk by the server. + while (true) + { + Object obj = in.readObject(); + if (obj instanceof ChatMessage) + { + ChatMessage msg = (ChatMessage) obj; + String sender = msg.getSender(); + String content = msg.getContent(); + switch (msg.getType()) + { + case PUBLIC_MESSAGE -> { + System.out.println("[Public] "+sender+": "+content); + } + case PRIVATE_MESSAGE -> { + if ("Server".equals(sender)) + { + System.out.println("[Server] "+content); + } else + { + System.out.println("[Private] "+sender+": "+content); + } + } + case USER_LIST -> { + System.out.println("Online users: "+content); + } + case LOGIN_SUCCESS -> { + System.out.println("[Server] "+content); + } + default -> { + System.out.println(sender+": "+content); + } + } + } else if (obj instanceof FileMessage) + { + FileMessage file = (FileMessage) obj; + System.out.println("Received file "+file.getFilename()+" from "+ file.getSender()); + } + } } catch (Exception e){ System.out.println("Disconnected from server"); } diff --git a/src/main/java/com/university/chat/Client/chatClient.java b/src/main/java/com/university/chat/Client/chatClient.java index dae0bad..84f9209 100644 --- a/src/main/java/com/university/chat/Client/chatClient.java +++ b/src/main/java/com/university/chat/Client/chatClient.java @@ -1,18 +1,81 @@ package com.university.chat.Client; +import com.university.chat.Common.ChatMessage; +import com.university.chat.Common.FileMessage; +import com.university.chat.Common.MessageType; + +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.Socket; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Scanner; + public class chatClient { public static void main() { - // TODO: Connecting to the server + // Connecting to the server // 1. Create a socket and connect to the server // 2. Create an ObjectOutputStream (out) and ObjectInputStream (in) // from the socket's streams — output FIRST, then input. // 2. Get the username, and send a LOGIN ChatMessage with that username - // 3. Start a new Thread running a ServerListener(in) so incoming - // messages are handled concurrently. + // 3. Start a new Thread running a ServerListener(in) so incoming messages are handled concurrently. - while (true){ + Socket socket = null; + ObjectOutputStream out = null; + ObjectInputStream in = null; + Scanner scanner = null; + String username = null; + + try + { + socket = new Socket("localhost", 12345); + out = new ObjectOutputStream(socket.getOutputStream()); + out.flush(); + in = new ObjectInputStream(socket.getInputStream()); + scanner = new Scanner(System.in); + + System.out.println("Enter your username: "); + username = scanner.nextLine().trim(); + if (username.isEmpty()) + { + System.out.println("Username cannot be empty!"); + return; + } + + ChatMessage loginMsg = new ChatMessage(MessageType.LOGIN, username, null, username); + out.writeObject(loginMsg); + out.flush(); + + Object response = in.readObject(); + if (response instanceof ChatMessage) + { + ChatMessage loginRespose = (ChatMessage) response; + if (loginRespose.getType() == MessageType.LOGIN_FAILED) + { + System.out.println("Login failed: "+loginRespose.getContent()); + return; + } else if (loginRespose.getType() == MessageType.LOGIN_SUCCESS) + { + System.out.println("Login successful: "+loginRespose.getContent()); + } + } + + ServerListener serverListener = new ServerListener(in); + Thread listener = new Thread(serverListener); + listener.setDaemon(true); + listener.start(); + + } catch (Exception e) + { + System.out.println(e.getMessage()); + return; + } + + boolean running = true; + while (running){ try { - // TODO: Program loop — read a line from the console and act on it: + // Program loop — read a line from the console and act on it: // - "/msg " -> build & send a PRIVATE_MESSAGE // - "/users" -> build & send a USER_LIST request // - "/sendfile " -> read the file into a byte[] @@ -21,9 +84,81 @@ public class chatClient { // and send it as a FileMessage // - anything else -> send a PUBLIC_MESSAGE // Remember to flush() the output stream after writeObject(). + + System.out.println("> "); + String line = scanner.nextLine(); + if (line == null) continue; + line = line.trim(); + if (line.isEmpty()) continue; + + if (line.equals("/exit")) { + System.out.println("Goodbye!"); + running = false; + break; + } + if (line.startsWith("/msg")) + { + String[] parts = line.split(" ", 3); + if (parts.length < 3) + { + System.out.println("Usage: /msg "); + continue; + } + + String receiver = parts[1]; + String content = parts[2]; + ChatMessage msg = new ChatMessage(MessageType.PRIVATE_MESSAGE, username, receiver, content); + out.writeObject(msg); + out.flush(); + } else if (line.startsWith("/sendfile")) + { + String[] parts = line.split(" ", 3); + if (parts.length < 3) + { + System.out.println("Usage: /sendfile "); + continue; + } + String receiver = parts[1]; + String filepath =parts[2]; + Path path = Paths.get(filepath); + if(!Files.exists(path) || Files.isDirectory(path)) + { + System.out.println("File not found or is a directory."); + continue; + } + byte[] data = Files.readAllBytes(path); + String filename = path.getFileName().toString(); + FileMessage fileMsg = new FileMessage(username, receiver, filename, data); + out.writeObject(fileMsg); + out.flush(); + System.out.println("File sent: "+filename+" to "+receiver); + } else if (line.equals("/users")) { + ChatMessage msg = new ChatMessage(MessageType.USER_LIST, username, null, ""); + out.writeObject(msg); + out.flush(); + } else + { + ChatMessage msg = new ChatMessage(MessageType.PUBLIC_MESSAGE, username, null, line); + out.writeObject(msg); + out.flush(); + } + } catch (Exception e){ System.out.println("command failed: " + e.getMessage()); + running = false; + break; } } + + try + { + if (scanner != null) scanner.close(); + if (out != null) out.close(); + if (in != null) in.close(); + if (socket != null) socket.close(); + } catch (Exception e) + { + System.out.println(e.getMessage()); + } } }