关闭连接后无法通过本地端口连接

时间:2012-06-17 20:07:58

标签: java networking network-programming hole-punching

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

我有这段简单的代码试图打开与特定本地端口上的服务器的连接。我试图在公共服务器上观察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错误 - 地址已在使用中:connect

2012-06-17 15:55:25,175 DEBUG - 详情: java.net.BindException:地址已在使用中:connect     at java.net.PlainSocketImpl.socketConnect(Native Method)〜[na:1.6.0_24]     在java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)〜[na:1.6.0_24]     在java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)〜[na:1.6.0_24]     在java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)〜[na:1.6.0_24]     在java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)〜[na:1.6.0_24]     在java.net.Socket.connect(Socket.java:529)〜[na:1.6.0_24]     在java.net.Socket.connect(Socket.java:478)〜[na:1.6.0_24]     在java.net.Socket。(Socket.java:375)〜[na:1.6.0_24]     在java.net.Socket。(Socket.java:249)〜[na:1.6.0_24]

3 个答案:

答案 0 :(得分:1)

尝试在connection.close();。

之前直接添加connection.setSoLinger(true, 0);

像这样:

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

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

答案 1 :(得分:0)

选择当地港口的依据是什么?显然不是一个合理的。如果您需要,最好让系统选择它,指定零,并在打开后从插槽中获取实际值

答案 2 :(得分:0)

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

Socket connection = new Socket();
connection.setReuseAddress(true);
connection.bind( ...);