title: Making file transfer more efficient Java
body: <p>I have two wireless computers connected to an N wireless router. Each of these PCs are connected at between 108-150Mbps. </p>
  
  <p>Theoretically, I should be able to transfer at 13.5MB/s to 18.75MB/s, under the absolute best of conditions.</p>
  
  <p>The first computer (that is sending), uses a very fast SSD, which is around 100MB/s if I remember correctly. CPU usage also stays below 20%.</p>
  
  <p>It sent 1960273535 bytes (1.8GB) in 656367ms. That's 2.8MB/s (22 out of 108 Megabits).
  When I open up task manager, I see that only 25-27% of the network connection is being used.</p>
  
  <p>I am looking for any ideas, suggestions, or improvements that can make the transfer faster (over a network). I was thinking of buffering the file from the disk on a thread and sending the buffered data from another thread but I'm not sure if it's a good idea.
  Here is the SSCCE:</p>
  
  <p>Host:</p>
  
  <pre><code>import java.io.*;
  import java.net.*;
  
  
  public class Host {
  
  
      public static void main(String[] args) throws IOException {
  
  
          ServerSocket servsock = new ServerSocket(15064);
          Socket sock = servsock.accept();
              long time = System.currentTimeMillis();
  
          OutputStream out = sock.getOutputStream();
          FileInputStream fileInputStream = new FileInputStream("C:\\complete.rar");
  
          byte [] buffer = new byte[64*1024]; 
          int bytesRead = 0;
          long totalSent = 0;
  
          while ( (bytesRead = fileInputStream.read(buffer)) != -1)
          {
              if (bytesRead &gt; 0)
              {   
                  out.write(buffer, 0, bytesRead);
                  totalSent += bytesRead;
                  System.out.println("sent " + totalSent);
              }   
          }
  
          sock.close();
  
          System.out.println("Sent " + totalSent + " bytes in "
                  + (System.currentTimeMillis() - time) + "ms.");
  
      }
  }
  </code></pre>
  
  <p>Client:</p>
  
  <pre><code>import java.io.*;
  import java.net.*;
  
  public class Client {
  
      public static void main(String[] args) throws Exception {
          Socket sock = new Socket("127.0.0.1", 15064);
          InputStream in = sock.getInputStream();
          FileOutputStream fileOutputStream = new FileOutputStream("output.rar");
  
          byte [] buffer = new byte[64*1024]; 
          int bytesRead = 0;
  
          while ( (bytesRead = in.read(buffer)) != -1)
              fileOutputStream.write(buffer, 0, bytesRead);
          sock.close();
          fileOutputStream.close();
      }
  }
  </code></pre>
  
  <p>Edit: I tried mapping a network drive and sending the file over that, and windows did even worse - 2.35MB/s. According to this article <a href="http://tinyurl.com/634qaqg" rel="nofollow">http://tinyurl.com/634qaqg</a> mapping a network drive is faster than FTP, and I also don't have the time to stay playing around and setting up the FTP server.</p>
  
  <p>Edit2: After changing the timer, turns out it was transferring at 3MB/s over WiFi. I hate the "theoretical" throughput. When I buy something, I want to know it's REAL performance.
  It turns out the code is indeed limited by WiFi speeds. I am still open to suggestions though.</p>
  
  <p>Edit 3: After running the program on 100Mbps LAN, it managed to transfer the file at 11.8MB/s. That's pretty good considering that the maximum transfer rate is 12.5MB/s.</p>