2

我正在尝试按照本文http://www.brynosaurus.com/pub/net/p2pnat/中的描述对 NAT 的 TCP 打孔进行原型设计。

我有这段简单的代码,它试图在特定本地端口上打开与服务器的连接。我试图在公共服务器上观察 NAT 是否将两个连接都映射到同一个 NAT 映射。

int localPort = getFreeLocalPort();

     while (true) {

        Socket connection = new Socket(_publicServerHost,_publicServerPort,
                 getLocalSocketAddress(), localPort);

        connection.setReuseAddress(true);

        connection.close();

     }

第一次连接正常。但是第二次尝试它会引发异常:

选择用于打孔的本地端口:65416

2012-06-17 15:55:21,545 错误 - 地址已在使用中:连接

2012-06-17 15:55:25,175 调试 - 详细信息:java.net.BindException:地址已在使用中:在 java.net.PlainSocketImpl.socketConnect(Native Method) 处连接 ~[na:1.6.0_24] 在 java.net .PlainSocketImpl.doConnect(PlainSocketImpl.java:351) ~[na:1.6.0_24] at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213) ~[na:1.6.0_24] at java.net.PlainSocketImpl.connect (PlainSocketImpl.java:200) ~[na:1.6.0_24] at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366) ~[na:1.6.0_24] at java.net.Socket.connect(Socket.java :529) ~[na:1.6.0_24] at java.net.Socket.connect(Socket.java:478) ~[na:1.6.0_24] at java.net.Socket.(Socket.java:375) ~[ na:1.6.0_24] 在 java.net.Socket.(Socket.java:249) ~[na:1.6.0_24]

4

3 回答 3

1

尝试connection.setSoLinger(true, 0);在 connection.close(); 之前直接添加。

像这样:

connection.setSoLinger(true, 0);
connection.close();

这会强制操作系统释放套接字。

于 2012-06-17T20:13:41.320 回答
0

选择本地港口的依据是什么?显然不是一个健全的人。您最好让系统选择它,通过指定零,并在打开后套接字获取实际值(如果您需要它)。

于 2012-06-17T21:28:49.500 回答
0

你解决了你的问题吗?应在分配端口之前调用 setReuseAddress()。

Socket connection = new Socket();
connection.setReuseAddress(true);
connection.bind( ...);
于 2013-02-20T13:39:50.813 回答