【发布时间】:2013-09-12 19:05:28
【问题描述】:
我正在开发一个涉及基于 TCP 的 P2P 通信的 Java 客户端/服务器应用程序。我正在尝试按照此处所述实现 TCP 打孔:http://www.brynosaurus.com/pub/net/p2pnat/#sec-tcp。这需要同时侦听并尝试使用相同的本地 TCP 端口建立传出连接。显然,如果使用了SO_REUSEADDR 套接字选项,这应该可以工作,我是通过Java 中的setReuseAddress() 方法设置的。但是,这并没有像我预期的那样工作。下面是一些测试代码:
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) { }
}
}
}
}
这在 Windows 7 中按预期工作:ServerSocket 在其自己的线程中侦听端口 7077,并且 Socket 反复尝试连接到 192.168.0.103:7077。但是,在 Linux (Ubuntu) 下,只有第一次 Socket 连接尝试有效,随后的尝试会得到“地址已在使用中”BindException。我是否应该能够从同时监听的 TCP 源端口建立传出连接,并在关闭套接字后立即重用本地端口号,因为我启用了 SO_REUSEADDR 选项?
【问题讨论】:
-
不确定这里是否有您的问题的答案:stackoverflow.com/questions/14388706/… 但绝对值得一读。
标签: java linux sockets networking tcp