title: Java TCP socket: data transfer is slow
body: <p>I set up a server with a ServerSocket, connect to it with a client machine.  They're directly networked through a switch and the ping time is &lt;1ms.</p>
  
  <p>Now, I try to push a "lot" of data from the client to the server through the socket's output stream.  It takes 23 minutes to transfer 0.6Gb.  I can push a much larger file in seconds via scp.</p>
  
  <p>Any idea what I might be doing wrong?  I'm basically just looping and calling writeInt on the socket.  The speed issue doesn't matter where the data is coming from, even if I'm just sending a constant integer and not reading from disk.</p>
  
  <p>I tried setting the send and receive buffer on both sides to 4Mb, no dice.  I use a buffered stream for the reader and writer, no dice.</p>
  
  <p>Am I missing something?</p>
  
  <p>EDIT: code</p>
  
  <p>Here's where I make the socket</p>
  
  <pre><code>System.out.println("Connecting to " + hostname);
  
      serverAddr = InetAddress.getByName(hostname);
  
      // connect and wait for port assignment
      Socket initialSock = new Socket();
      initialSock.connect(new InetSocketAddress(serverAddr, LDAMaster.LDA_MASTER_PORT));
      int newPort = LDAHelper.readConnectionForwardPacket(new DataInputStream(initialSock.getInputStream()));
      initialSock.close();
      initialSock = null;
  
      System.out.println("Forwarded to " + newPort);
  
      // got my new port, connect to it
      sock = new Socket();
      sock.setReceiveBufferSize(RECEIVE_BUFFER_SIZE);
      sock.setSendBufferSize(SEND_BUFFER_SIZE);
      sock.connect(new InetSocketAddress(serverAddr, newPort));
  
      System.out.println("Connected to " + hostname + ":" + newPort + " with buffers snd=" + sock.getSendBufferSize() + " rcv=" + sock.getReceiveBufferSize());
  
      // get the MD5s
      try {
          byte[] dataMd5 = LDAHelper.md5File(dataFile),
                 indexMd5 = LDAHelper.md5File(indexFile);
  
          long freeSpace = 90210; // ** TODO: actually set this **
  
          output = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream()));
          input  = new DataInputStream(new BufferedInputStream(sock.getInputStream()));
  </code></pre>
  
  <p>Here's where I do the server-side connection:</p>
  
  <pre><code>    ServerSocket servSock = new ServerSocket();
      servSock.setSoTimeout(SO_TIMEOUT);
      servSock.setReuseAddress(true);
      servSock.bind(new InetSocketAddress(LDA_MASTER_PORT));
  
      int currPort = LDA_START_PORT;
  
      while (true) {
          try {
              Socket conn = servSock.accept();
              System.out.println("Got a connection.  Sending them to port " + currPort);
              clients.add(new MasterClientCommunicator(this, currPort));
              clients.get(clients.size()-1).start();
  
              Thread.sleep(500);
  
              LDAHelper.sendConnectionForwardPacket(new DataOutputStream(conn.getOutputStream()), currPort);
  
              currPort++;
          } catch (SocketTimeoutException e) {
              System.out.println("Done listening.  Dispatching instructions.");
              break;
          }
          catch (IOException e) {
              e.printStackTrace();
          }
          catch (Exception e) {
              e.printStackTrace();
          }
      }
  </code></pre>
  
  <p>Alright, here's where I'm shipping over ~0.6Gb of data.</p>
  
  <pre><code>public static void sendTermDeltaPacket(DataOutputStream out, TIntIntHashMap[] termDelta) throws IOException {
      long bytesTransferred = 0, numZeros = 0;
  
      long start = System.currentTimeMillis();
  
      out.write(PACKET_TERM_DELTA); // header     
      out.flush();
      for (int z=0; z &lt; termDelta.length; z++) {
          out.writeInt(termDelta[z].size()); // # of elements for each term
          bytesTransferred += 4;
      }
  
      for (int z=0; z &lt; termDelta.length; z++) {
          for (int i=0; i &lt; termDelta[z].size(); i++) {
              out.writeInt(1);
              out.writeInt(1);
          }
      }
  </code></pre>
  
  <p>It seems pretty straightforward so far...</p>