diff --git a/.gitignore b/.gitignore index 36d1f49..4e9d446 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,4 @@ hs_err_pid* replay_pid* -my_passwords.txt \ No newline at end of file +mypasswords.txt \ No newline at end of file diff --git a/my_passwords.txt b/my_passwords.txt deleted file mode 100644 index 0332ee1..0000000 --- a/my_passwords.txt +++ /dev/null @@ -1,2 +0,0 @@ -You can add your passwords here and they won't be committed to your git repository. - diff --git a/src/ChatterboxClient.java b/src/ChatterboxClient.java index 9f80fc0..1ad4d07 100644 --- a/src/ChatterboxClient.java +++ b/src/ChatterboxClient.java @@ -2,7 +2,10 @@ import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.Scanner; @@ -48,7 +51,7 @@ public class ChatterboxClient { * Example: * javac src/*.java && java -cp src ChatterboxClient localhost 12345 sharon abc123 * - * This method is already complete. Your work is in the TODO methods below. + * This method is already complete. Your work is in the other methods below. */ public static void main(String[] args) { ChatterboxOptions options = null; @@ -125,9 +128,10 @@ public static void main(String[] args) { * @throws IllegalArgumentException on any bad/missing input */ public static ChatterboxOptions parseArgs(String[] args) throws IllegalArgumentException { - // TODO: read args in the required order and return new ChatterboxOptions(host, port, username, password) - // Remove this exception - throw new UnsupportedOperationException("Argument parsing not yet implemented. Implement parseArgs and remove this exception"); + if (args.length != 4) throw new IllegalArgumentException("Argument length invalid"); + int portCheck = Integer.parseInt(args[1]); + if (portCheck < 1 || portCheck > 65535) throw new IllegalArgumentException("Port number invalid"); + return new ChatterboxOptions(args[0], portCheck, args[2], args[3]); } /** @@ -146,8 +150,10 @@ public ChatterboxClient(ChatterboxOptions options, InputStream userInput, Output this.userInput = new Scanner(userInput, StandardCharsets.UTF_8); this.userOutput = userOutput; - throw new UnsupportedOperationException("Constructor not yet implemented. Implement ChatterboxClient constructor and remove this exception"); - // TODO: copy options.getHost(), getPort(), getUsername(), getPassword() into fields + this.host = options.getHost(); + this.port = options.getPort(); + this.username = options.getUsername(); + this.password = options.getPassword(); } /** @@ -164,10 +170,20 @@ public ChatterboxClient(ChatterboxOptions options, InputStream userInput, Output * @throws IOException if the socket cannot be opened */ public void connect() throws IOException { - throw new UnsupportedOperationException("Connect not yet implemented. Implement connect() and remove this exception!"); + Socket socket = new Socket(host, port); - // Make sure to have this.serverReader and this.serverWriter set by the end of this method! - // hint: get the streams from the sockets, use those to create the InputStreamReader/OutputStreamWriter and the BufferedReader/BufferedWriter + try { + InputStream inputStream = socket.getInputStream(); + InputStreamReader inputStreamReader = new InputStreamReader(inputStream, java.nio.charset.StandardCharsets.UTF_8); + this.serverReader = new BufferedReader(inputStreamReader); + + OutputStream outputStream = socket.getOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, java.nio.charset.StandardCharsets.UTF_8); + this.serverWriter = new BufferedWriter(outputStreamWriter); + } catch (IOException e) { + System.err.println("Error opening socket"); + System.err.println(e.getMessage()); + } } /** @@ -178,7 +194,7 @@ public void connect() throws IOException { * to userOutput. * - Send ONE LINE containing: * username + " " + password + "\n" - * using serverOutput. + * using serverWriter. * - Read ONE response line from serverReader. * - If the response indicates failure, throw IllegalArgumentException * with that response text. @@ -191,9 +207,27 @@ public void connect() throws IOException { * @throws IllegalArgumentException for bad credentials / server rejection */ public void authenticate() throws IOException, IllegalArgumentException { - throw new UnsupportedOperationException("Authenticate not yet implemented. Implement authenticate() and remove this exception!"); - // Hint: use the username/password instance variables, DO NOT READ FROM userInput - // send messages using serverWriter (don't forget to flush!) + String line = serverReader.readLine(); + if (line != null) { + userOutput.write(line.getBytes()); + } + + userOutput.write((getUsername() + " " + getPassword()).getBytes()); + serverWriter.write(getUsername() + " " + getPassword()); + serverWriter.newLine(); + serverWriter.flush(); + + userOutput.write(10); // 10 represents a newline in ASCII + + line = serverReader.readLine(); + if (line.contains("fail")) throw new IllegalArgumentException(line); + + userOutput.write(line.getBytes()); + userOutput.write(10); + line = serverReader.readLine(); + userOutput.write(line.getBytes()); + userOutput.write(10); + return; } /** @@ -209,7 +243,11 @@ public void authenticate() throws IOException, IllegalArgumentException { * @throws IOException */ public void streamChat() throws IOException { - throw new UnsupportedOperationException("Chat streaming not yet implemented. Implement streamChat() and remove this exception!"); + Thread incoming = new Thread(() -> printIncomingChats()); + Thread outgoing = new Thread(() -> sendOutgoingChats()); + + incoming.start(); + outgoing.start(); } /** @@ -227,8 +265,20 @@ public void streamChat() throws IOException { * print a message to userOutput and exit. */ public void printIncomingChats() { - // Listen on serverReader - // Write to userOutput, NOT System.out + try { + String line; + while((line = serverReader.readLine()) != null) { + userOutput.write(line.getBytes()); + userOutput.write(10); + } + } catch (IOException e) { + try { + userOutput.write(("Disconnected from server").getBytes()); + System.exit(1); + } catch (IOException x) { + System.err.println(x.getMessage()); + } + } } /** @@ -244,9 +294,22 @@ public void printIncomingChats() { * print a message to userOutput and exit. */ public void sendOutgoingChats() { - // Use the userInput to read, NOT System.in directly - // loop forever reading user input - // write to serverOutput + while(userInput.hasNextLine()) + { + try { + String input = userInput.nextLine(); + serverWriter.write(input); + serverWriter.newLine(); + serverWriter.flush(); + } catch (IOException e) { + try { + userOutput.write(("Disconnected from server").getBytes()); + System.exit(1); + } catch (IOException x) { + System.err.println(x.getMessage()); + } + } + } } public String getHost() {