title: HTTP Vs Vanilla sockets for uploading large binary file (50-200 MB) from Android device over a single hop Wi-Fi Network
body: <p>Is there a substantial overhead of using HTTP over plain sockets (Java on Android) to send a large (50-200 MB) file [file is on the SD card] from an Android device to a Linux server over a Wi-Fi network. </p>
  
  <p>In my current prototype I'm using CherryPy-3.2.0 to implement my HTTP server. I'm running Android 2.3.3 on a Nexus one as my client. </p>
  
  <p>Currently it's taking around ~100 seconds** (on slower network 18 Mbps*) and ~50 seconds (on a faster 54 Mbps*) Wi-Fi network to upload a 50 MB binary file. </p>
  
  <p>NOTE:<br>
  *<em>I'm using <code>WifiInfo.getLinkSpeed()</code> to measure the network link speed</em></p>
  
  <p>** <em>This is the time difference before and after the <code>HTTPClient.execute(postRequest)</code></em></p>
  
  <p>Any other ideas regarding other expensive operations that may have a substantial part in the total time apart from the network and how to reduce this time would be appreciated. </p>
  
  <p>Thanks. </p>
  
  <p>EDIT - HTTP post code on Android</p>
  
  <pre><code>private void doHttpPost(String fileName) throws Exception{
  
      HttpParams httpParameters = new BasicHttpParams();
  
      // Set the timeout in milliseconds until a connection is established.
      int timeoutConnection = 9000000;
      HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
      // Set the default socket timeout (SO_TIMEOUT) 
      // in milliseconds which is the timeout for waiting for data.
      int timeoutSocket = 9000000;
      HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
  
      HttpClient client = new DefaultHttpClient(httpParameters);
  
      client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109);
  
      HttpPost postRequest = new HttpPost();
      postRequest.setURI(new URI("http://192.168.1.107:9999/upload/"));
  
      MultipartEntity multiPartEntity = new MultipartEntity();
      multiPartEntity.addPart("myFile", new FileBody(new File(fileName)));
      postRequest.setEntity(multiPartEntity);
  
      long before = TrafficStats.getTotalTxBytes();
      long start = System.currentTimeMillis();
      HttpResponse response = client.execute(postRequest);
      long end = System.currentTimeMillis(); 
      long after = TrafficStats.getTotalTxBytes();
  
      Log.d(LOG_TAG, "HTTP Post Execution took " + (end - start) + " ms.");
  
  
      if( before != TrafficStats.UNSUPPORTED &amp;&amp; after != TrafficStats.UNSUPPORTED)
          Log.d(LOG_TAG, (after-before) + " bytes transmitted to the server");
      else
          Log.d(LOG_TAG, "This device doesnot support Network Traffic Stats");
  
      HttpEntity responseEntity = response.getEntity();
  
  
      if (responseEntity != null) {
          responseEntity.consumeContent();
          Log.d(LOG_TAG, "HTTP Post Response " + response.getEntity().getContent().toString() );
      }
  
      client.getConnectionManager().shutdown(); 
  
  }
  </code></pre>
  
  <p>EDIT 2: Based on the results reported by this tool it looks like the SD card read speed is not an issue. So it may either be the HttpClient library or something else. 
  <img src="https://i.stack.imgur.com/Vw2a3.jpg" alt="enter image description here">
  <img src="https://i.stack.imgur.com/7SvyA.jpg" alt="enter image description here"></p>