2014-01-27 62 views
0

所以我建立了一个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(); 
    } 

当我到达第三个和最后一个绑定,我得到“绑定异常:地址已经在使用”。我google了起来,看到前面的插座仍然可能挂在某物上,并没有关闭,等等。

编辑:这只发生在一些电脑上。在其他情况下,结合一切都没有问题

编辑:使用“netstat的”,我可以看到连接被挂在电脑上“SYN_SENT”状态,其中绑定出错

任何人有任何为什么会发生这种情况的提示或如何绕过它?

+0

正确关闭TCP套接字。只是调用“close”是不够的。你需要关闭发送端,然后继续尝试接收,直到你正常关闭,然后你可以在你身边调用close。 –

+0

在windows中,您可以使用'pid'来检查控制面板中哪个端口已被使用。 – Prince

+0

@DavidSchwartz在该连接处没有建立连接。这只是为了打开防火墙例外以允许传入的流量。这意味着我不能关闭发送端,也不会收到“close”。 – BlueMoon93

回答

0

好吧,那么。答案是......你无法绕过它。这是一个操作系统功能,它使tcp连接挂在这个端口上。在某些电脑上可能需要5秒钟才能清除。在其他情况下,可能需要2分钟以上。

现在,我已经做了什么来解决这个问题......好吧,我唯一能想到的就是。当程序启动时,它会检查它是否支持TCP打孔或其他绕过防火墙的方式。当建立呼叫时,对等方将根据他们可以做的事情交换参数,并从给定的优先级列表中选择他们都支持的方法。

就我而言,在我的电脑上,TCP Hole Punch可以工作。在我妈妈的笔记本电脑中,它并没有采用其他技术(UDP Hole Punch,UPnP,SOCKS等)

相关问题