title: Java TCP File Transfer Only Complete On First Attempt
body: <p>Despite hours of researching this problem, I have made very little progress. According to my professor, the code should be working as written...</p>
  
  <p>I have a server that stays open, and a client that requests a file. Once the client receives the file, the client closes.</p>
  
  <p>When I open the server, I am able to transfer a complete .jpg image file. The client then closes while the server remains open. I start up another client and try to transfer the same image, and only a portion of the bytes are transferred/written to the disk. The file transfer is only completely successful for the first file transferred by the server!</p>
  
  <p>Additionally strange, a simple .txt text file <em>never</em> successfully transfers. I believe the cause is on the server side because it remains open as opposed to the client, which starts over each time.</p>
  
  <p>Server Code:</p>
  
  <pre><code>import java.io.*;
  import java.net.*;
  import java.util.Arrays;
  
  class ft_server {
  
      public static void main(String args[]) throws Exception {
  
          /*
           * Asks user for port number and listens on that port
           */
          BufferedReader portFromUser = new BufferedReader(new InputStreamReader(System.in));
          System.out.println("Enter the port you'd like to use: ");
          int portNumber = Integer.valueOf(portFromUser.readLine());
  
          if (portNumber &lt; 1 || portNumber &gt; 65535) {
              System.out.println("Please choose a port number between 1 and 65535.");
              return;
          }
          portFromUser.close();
  
  
          ServerSocket listenSocket = new ServerSocket(portNumber);
          /*
           * Finished with user input
           */
  
          /*
           * Continuously listens for clients:
           */
          while (true) {
              Socket clientSocket = listenSocket.accept();
              BufferedReader inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
              DataOutputStream outToClient = new DataOutputStream(clientSocket.getOutputStream());
  
              String clientIP = clientSocket.getRemoteSocketAddress().toString();
              System.out.println("The client " + clientIP + " connected!");
  
              String clientMessage = inFromClient.readLine();
              System.out.println("The client requested file: " + clientMessage);
  
              // Get file. If doesn't exist, let's client know.
              // Otherwise informs client of file size.
              File myFile = new File(clientMessage);
  
              if (!myFile.exists()) {
                  outToClient.writeBytes("File does not exist!\n");
                  return;
              } else {
                  outToClient.writeBytes(String.valueOf((int)myFile.length()) + "\n");
              }
  
              // Create array for storage of file bytes:
              byte[] byteArray = new byte[(int)myFile.length()];
              BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
  
              // Read file into array:
              bis.read(byteArray, 0, byteArray.length);
  
              // Send the file:
              outToClient.write(byteArray, 0, byteArray.length);
  
              outToClient.close();
              clientSocket.close();
          }
      }
  }
  </code></pre>
  
  <p>Client Code:</p>
  
  <pre><code>import java.io.*;
  import java.net.*;
  
  class ft_client {
  
      public static void main(String args[]) throws Exception {
  
          int byteSize = 2022386;
          int bytesRead;
  
          /*
           * Asks user for IP and port:
           */
          BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
          System.out.println("Enter an IP address: ");
          String ipAddress = inFromUser.readLine();
          System.out.println("Enter a port: ");
          String port = inFromUser.readLine();
  
          Socket clientSocket;
  
          try {
              // Makes socket, port, and calls connect. Assumes it's TCP:
              clientSocket = new Socket(ipAddress, Integer.valueOf(port));
          } catch (Exception e) {
              System.out.println(e.getMessage());
              return;
          }
  
          // Creates InputStream from server to get file size and other messages:
          BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
  
          // Anything written to this will be sent to the server:
          DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
  
          // Asks for a file name to download from the server:
          System.out.println("What file do you want?: ");
          String message = inFromUser.readLine();
          outToServer.writeBytes(message + "\n");
          inFromUser.close();
  
          // Listens for confirmation from server.
          // If the file exists, the file size is delivered here:
          String response = inFromServer.readLine();
          System.out.println("File size: " + response);
          if (response.equals("File does not exist!")) {
              return;
          }
  
          // Receives file from server:
          byteSize = (int) Integer.valueOf(response);
          byte[] byteArray = new byte[byteSize];
          InputStream is = clientSocket.getInputStream(); // calling clientSocket.getInputStream() twice???
          FileOutputStream fos = new FileOutputStream(message);
          BufferedOutputStream bos = new BufferedOutputStream(fos);       
  
          // Continuously writes the file to the disk until complete:
          int total = 0;
          while ((bytesRead = is.read(byteArray)) != -1) {
              bos.write(byteArray, 0, bytesRead);
              total += bytesRead;
          }
  
          bos.close();
          System.out.println("File downloaded (" + total + " bytes read)");
  
          clientSocket.close();
      }
  }
  </code></pre>
  
  <p>Are buffered readers interfering with output streams? Is there a better way to transfer files?</p>