diff --git a/src/main/java/edu/unl/cse/csce361/socket_chat/Chat.java b/src/main/java/edu/unl/cse/csce361/socket_chat/Chat.java
index b99ffa43ec69f9be2cae5606f8addc13f46d3294..8d866d83e8540950e730ce3f6caf505385155cc1 100644
--- a/src/main/java/edu/unl/cse/csce361/socket_chat/Chat.java
+++ b/src/main/java/edu/unl/cse/csce361/socket_chat/Chat.java
@@ -1,86 +1,39 @@
 package edu.unl.cse.csce361.socket_chat;
 
 import java.io.*;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
+import java.net.*;
 import java.util.InputMismatchException;
 import java.util.Scanner;
 
+import static java.lang.Thread.sleep;
+
 public class Chat {
 
+    private static final int MAXIMUM_CONNECTION_ATTEMPTS = 10;
     private Socket socket;
     private Scanner scanner;
     private boolean isHost;
 
     public Chat() {
         scanner = new Scanner(System.in);
-        try {
-            socket = connect();
-        } catch (IOException ioException) {
-            System.err.println("Connection failed: " + ioException);
-            System.exit(1);
-        }
-    }
-
-    @SuppressWarnings("WeakerAccess")
-    public void communicate() {
-        try {
-            communicate(
-                    new BufferedReader(new InputStreamReader(System.in)),
-                    new BufferedReader(new InputStreamReader(socket.getInputStream())),
-                    System.out,
-                    new PrintStream(socket.getOutputStream()));
-            socket.close();
-        } catch (IOException ioException) {
-            System.err.println("Connection dropped: " + ioException);
-            System.exit(1);
-        }
-    }
-
-    @SuppressWarnings("SameParameterValue")
-    private void communicate(BufferedReader localInput,
-                             BufferedReader remoteInput,
-                             PrintStream localOutput,
-                             PrintStream remoteOutput) {
-        System.out.println("Connection established. Host goes first.");
-        String message = "";
-        boolean myTurnToTalk = isHost;
-        try {
-            while (!message.equals("EXIT")) {
-                if (myTurnToTalk) {
-                    message = localInput.readLine();
-                    remoteOutput.println(encipher(message));
-                } else {
-                    message = decipher(remoteInput.readLine());
-                    localOutput.println(message);
-                }
-                myTurnToTalk = !myTurnToTalk;
-            }
-        } catch (IOException ioException) {
-            System.err.println("Connection dropped: " + ioException);
-            System.exit(1);
-        }
+        socket = connect();
     }
 
-    private String encipher(String plaintext) {
-//        String ciphertext = ...;
-//        return ciphertext;
-        return plaintext;
-    }
+    // THESE METHODS SET UP CONNECTION
 
-    private String decipher(String ciphertext) {
-//        String plaintext = ...;
-//        return plaintext;
-        return ciphertext;
-    }
-
-    private Socket connect() throws IOException {
+    private Socket connect() {
         System.out.print("Are you the chat host? [Y] ");
         String answerString = scanner.nextLine().toUpperCase();
         char answer = answerString.length() > 0 ? answerString.charAt(0) : 'Y';
         isHost = (answer != 'N');
-        return isHost ? connectAsServer() : connectAsClient();
+        Socket socket = null;
+            try {
+                socket = isHost ? connectAsServer() : connectAsClient();
+            } catch (IOException ioException) {
+                System.err.println("Connection failed: " + ioException);
+                System.exit(1);
+            }
+        return socket;
     }
 
     private Socket connectAsServer() throws IOException {
@@ -98,7 +51,28 @@ public class Chat {
         String prompt = "Enter port host is opening at " +
                 address[0] + "." + address[1] + "." + address[2] + "." + address[3];
         int port = getPort(prompt);
-        return new Socket(InetAddress.getByAddress(address), port);
+        Socket socket = null;
+        int attemptCount = 0;
+        do {
+            try {
+                sleep(1000*attemptCount++);
+            } catch (InterruptedException ignored) {
+            }
+            try {
+                socket = new Socket(InetAddress.getByAddress(address), port);
+            } catch (ConnectException ignored) {
+                System.out.println("Attempt " + attemptCount + ": Chat server is not yet ready at " +
+                        address[0] + "." + address[1] + "." + address[2] + "." + address[3] + ":" + port);
+                if (attemptCount < MAXIMUM_CONNECTION_ATTEMPTS) {
+                    System.out.println("Will attempt to connect again in " + attemptCount + " seconds");
+                    socket = null;
+                } else {
+                    System.err.println("Exceeded maximum number of connection attempts. Terminating.");
+                    System.exit(1);
+                }
+            }
+        } while (socket == null);
+        return socket;
     }
 
     private byte[] getRemoteHostAddress() {
@@ -159,6 +133,66 @@ public class Chat {
         return port;
     }
 
+    // THESE METHODS PERFORM CHAT AFTER CONNECTION IS SET UP
+
+    @SuppressWarnings("WeakerAccess")
+    public void communicate() {
+        try {
+            communicate(
+                    new BufferedReader(new InputStreamReader(System.in)),
+                    new BufferedReader(new InputStreamReader(socket.getInputStream())),
+                    System.out,
+                    new PrintStream(socket.getOutputStream()));
+        } catch (IOException ioException) {
+            System.err.println("Failed to set up input/output streams: " + ioException);
+            System.err.println("Terminating.");     // I'm pretty sure this is recoverable if the client is waiting on the server
+            System.exit(1);
+        }
+        try {
+            socket.close();
+        } catch (IOException ioException) {
+            System.err.println("Error while closing socket: " + ioException);
+            // We're terminating anyway, note the error and continue normal termination
+        }
+    }
+
+    @SuppressWarnings("SameParameterValue")
+    private void communicate(BufferedReader localInput,
+                             BufferedReader remoteInput,
+                             PrintStream localOutput,
+                             PrintStream remoteOutput) {
+        System.out.println("Connection established. Host goes first.");
+        String message = "";
+        boolean myTurnToTalk = isHost;
+        try {
+            while (!message.equals("EXIT")) {
+                if (myTurnToTalk) {
+                    message = localInput.readLine();
+                    remoteOutput.println(encipher(message));
+                } else {
+                    message = decipher(remoteInput.readLine());
+                    localOutput.println(message);
+                }
+                myTurnToTalk = !myTurnToTalk;
+            }
+        } catch (IOException ioException) {
+            System.err.println("Connection dropped: " + ioException);
+            System.exit(1);
+        }
+    }
+
+    private String encipher(String plaintext) {
+//        String ciphertext = ...;
+//        return ciphertext;
+        return plaintext;
+    }
+
+    private String decipher(String ciphertext) {
+//        String plaintext = ...;
+//        return plaintext;
+        return ciphertext;
+    }
+
     public static void main(String[] args) {
         Chat chat = new Chat();
         chat.communicate();