所以我正在建立一个VoIP软件,我与另一个对等体的连接线程有一个UDP套接字(用于发送音频)和一个用于信令/文本的tcp套接字。现在,为了绕过防火墙和NAT,我需要使用TCP Hole打孔技术,这意味着我需要尝试从呼叫的这一侧连接,这将在防火墙和NAT中打开漏洞,然后我等待连接同一个端口和另一个端口应该能够连接到我。
try {
// UDP Socket
DatagramSocket callSocket = new DatagramSocket(null);
callSocket.setReuseAddress(true);
callSocket.bind(new InetSocketAddress(myIP, 0));
//Send/receive a few packets on callSocket
// Addresses to use
InetSocketAddress myAddress = new InetSocketAddress(myIP, callSocket.getLocalPort());
InetSocketAddress targetAddress = new InetSocketAddress(InetAddress.getByName("192.168.1.1"), 6800);
// TCP Hole Punch
Socket tcpSocket = new Socket();
tcpSocket.setReuseAddress(true);
tcpSocket.bind(myAddress);
try {
tcpSocket.connect(targetAddress, 50);
// this never connects. it's just meant to open a hole in a firewall
} catch (SocketTimeoutException ignore) {
System.out.println("Timeout!");
}
tcpSocket.close();
// Open up TCP socket
ServerSocket tcpTempSocket = new ServerSocket();
tcpTempSocket.setReuseAddress(true);
tcpTempSocket.bind(myAddress);
// accept connection and do stuff
} catch (Exception ex) {
ex.printStackTrace();
}
当我进入第3次和最后的绑定时,我得到“Bind Exception:Address in in use”。我用谷歌搜索并读到前一个插座仍然悬挂在某物上并且没有关闭等等。
编辑:这只发生在某些计算机上。在其他方面,它会在没有问题的情况下绑定所有内容
编辑:使用“netstat”,我可以看到绑定出错的计算机上的“SYN_SENT”状态挂起连接
任何人都有任何关于为什么会发生这种情况或如何绕过它的提示?
答案 0 :(得分:0)
好的,好的。答案是......你不能绕过它。这是一个操作系统功能,它使tcp连接挂起在此端口上。在某些计算机上,可能需要5秒才能清除。在其他方面,它可能需要2分钟。
现在,我为解决这个问题所做的就是......好吧,我唯一能想到的就是。当程序启动时,它会检查它是否支持tcp打孔或绕过防火墙的其他方法。在建立呼叫时,对等体将根据它们可以做的事情来交换参数,并从给定的优先级列表中选择它们都支持的方法。
就我而言,在我的电脑上,TCP Hole Punch可以工作。我的妈妈的笔记本电脑没有,我采用其他技术(UDP打孔,UPnP,SOCKS等)