title: TCP Hole Punching and setReuseAddress() on Linux
body: <p>I am working on a Java client/server application that involves P2P communication over TCP. I'm trying to implement TCP Hole Punching as described here: <a href="http://www.brynosaurus.com/pub/net/p2pnat/#sec-tcp" rel="nofollow">http://www.brynosaurus.com/pub/net/p2pnat/#sec-tcp</a>. This requires simultaneously listening on and attempting to establish an outgoing connection using the same local TCP port. Apparently, this should work if the <code>SO_REUSEADDR</code> socket option is used, which I am setting via the <code>setReuseAddress()</code> method in Java. However, this is not working as I expected. Here is some test code:</p>
  
  <pre><code>import java.io.IOException;
  import java.net.*;
  
     public class Test {
      public static void main(String args[]) {        
          new Thread() {
                  public void run() {
                      try {
                          ServerSocket ss = new ServerSocket();
                          ss.setReuseAddress(true);
                          ss.bind(new InetSocketAddress(7077));
                          ss.accept();
                      } catch (Exception e) {
                          System.out.println("ServerSocket exception: " + e.getMessage());
                      }
                  }
              }.start();
  
          Socket s;
  
          while (true) {
              s = new Socket();
              try {
                  s.setReuseAddress(true);
                  s.bind(new InetSocketAddress(7077));
                  s.connect(new InetSocketAddress("192.168.0.103", 7077));
                  break;
              } catch (Exception e) {
                  System.out.println("Socket exception: " + e.getMessage());
                  try { s.close(); } catch (IOException e1) { }
                  try { Thread.sleep(1000); } catch (InterruptedException e1) { }
              }
  
          }
  
      }
  
  }
  </code></pre>
  
  <p>This works as expected in Windows 7: the <code>ServerSocket</code> listens on port 7077 in its own thread and the Socket repeatedly attempts to connect to 192.168.0.103:7077. However, under Linux (Ubuntu) only the first Socket connection attempt works, and subsequent attempts get the "Address already in use" <code>BindException</code>. Shouldn't I be able to establish an outgoing connection from a TCP source port that I'm also listening on simultaneously, and to reuse the local port number immediately after closing the socket, since I have the <code>SO_REUSEADDR</code> option enabled?</p>