2012-01-11 127 views
17

我正在尝试使用mingw toolchain来实现使用windows socket打孔的TCP打孔。我认为这个过程是正确的,但似乎并不需要。我用this作为参考。TCP打孔

  1. 连接到服务器小号
  2. 小号发送到的路由器IP +它用于连接到小号端口
  3. S对于B
  4. 开始2个线程: 连接到的路由器与由小号
  5. 另一个线程发送来的信息
    • 一个线程试图在等待在相同的传入连接端口用于连接到它的路由器时,它连接到小号
  6. 做同样的

我在代码中没有问题,我想既然:

  • 一个确实得到了对方的IP和端口使用
  • 他们都是听在他们用来连接到他们的路由器时,他们用于连接到他们的服务器
  • 他们都连接到正确的IP和端口,但超时(代码错误10060

我错过了什么?

编辑:在进程资源管理器的帮助下,我看到一个客户端设法建立到对等端的连接。但同行似乎并未考虑建立联系。

这是我用Wireshark捕获的东西。为了示例,服务器S和客户端A在同一台PC上。服务器S侦听重定向到该PC的特定端口(8060)。 仍尝试右侧IP连接,因为它认为通过小号发送的一个公共地址是localhost,因此使用的小号而不是公网IP。(我已经由占位符替换公网IP)

wireshark

编辑2:我认为混乱是由于这样的事实,传入和outcoming连接请求数据相同的端口上转移。这似乎弄乱了连接状态,因为我们不知道哪个套接字将从端口获取数据。如果我引用MSDN:

SO_REUSEADDR套接字选项允许套接字强制绑定到 端口被其他插座。在调用与原始套接字 相同的端口上的绑定之前,第二个套接字调用setsockopt,其中将optname参数设置为SO_REUSEADDR,并将optval参数集 设置为布尔值TRUE第二个套接字成功绑定后,绑定到该端口的所有套接字的 行为不确定。

但在同一端口上说话是由TCP打洞技术要求打通孔

+0

那么你对TCP打孔的解决方案是什么?我对此感兴趣。 – petersaints 2012-04-04 16:23:31

+0

你能解决这个问题,并做TCP打孔? – pkrish 2012-06-19 14:33:39

+0

@pkrish我只设法启动同时打开TCP(请参阅所选答案的评论) – Giann 2012-06-21 09:11:36

回答

11

甲开始2个线程:
一个线程试图连接到B的路由器与用S
其他线程正在等待相同的端口上的传入连接发送的信息用于连接到它的路由器时,它连接到S

你不能用两个线程做这件事,因为它只是一个操作。每个进行出站连接的TCP连接也都在等待传入连接。您只需调用'connect',并且您都发送出站SYN以建立连接并等待入站SYN进行连接。

但是,您可能需要关闭与服务器的连接。当您已经建立了来自同一端口的连接时,您的平台可能不允许您从端口建立TCP连接。所以就像你开始TCP打孔一样,关闭与服务器的连接。绑定一个新的TCP套接字到同一个端口,并调用connect

+0

工作正常,但只有当'SYN'在它们都通过相应的NAT /路由器之前没有到达任何一个对等体。所以有一点时间问题。这是同时TCP打开。 但http://www.bford.info/pub/net/p2pnat/index.html在一个失败的连接请求事件中讨论了同时侦听套接字。我从来没有看到这项工作。 – Giann 2012-01-19 05:48:42

+0

如果失败,您可能(十字指头)能够立即重试并仍然有效。但是你不能依靠TCP打孔工作。 – 2012-01-19 05:53:41

+0

您是否知道在不同的NAT /路由器之后建立对等连接的其他可靠方法? – Giann 2012-01-19 08:11:20

0
  1. 使用Wireshark检查tcp连接请求(3-way Handhsake进程)是否正常运行。

  2. 确保您的侦听器线程正在使用select()来解复用描述符。

  3. sockPeerConect(用于连接其他节点的套接字)在Listener Thread中为FD_SET()。

  4. 确保您正在检查

    int Listener Thread() 
    { 
        while(true) 
        { 
         FD_SET(sockPeerConn); 
         FD_SET(sockServerConn); 
         FD_SET(nConnectedSock); 
         if (FD_ISSET(sockPeerConect) 
         { 
         /// and calling accept() in side the 
         nConnectedSock = accept(....); 
    
         } 
         if (FD_ISSET(sockServerConn) 
         { 
         /// receive data from Server 
         recv(sockServerConn); 
    
         } 
         if (FD_ISSET(nConnectedSock) 
         { 
         /// Receive data from Other Peer 
         recv(nConnectedSock); 
    
         } 
    
        } 
        } 
    

5.确保管子要同时启动对等连接A到B和B到A
6.Start监听器线程之前,与服务器的连接并Peer并具有用于接收服务器和客户端的单个监听器线程。

+0

我不明白为什么我必须使用套接字。它有什么变化? – Giann 2012-01-11 17:50:32

+0

它会通知该套接字上有什么东西可用。我们必须重复检查特定套接字上是否有可用的东西。 – 2012-01-11 18:13:43

+0

WSAETIMEDOUT ....确保您在NAT设置中输出所有端口的TCP流量。 – 2012-01-11 18:27:36

-3

不是每个路由器支持TCP打洞,请查看以下文件,其中详细解释:

Peer-to-Peer Communication Across Network Address Translators

+1

感谢您链接相同的参考我引用我的问题... – Giann 2012-01-17 07:53:34

+0

你可以添加一个网络布局为您的S,A和B和路由器,我怀疑,因为你有S和A在同一台机器上,所以你的NAT路由器甚至没有在路由器上进行NAT转换,以便B到达A,因为A没有通过路由器连接到S(它们在同一台计算机上!)。为了正确的测试,你应该把你的S不放在与A或B相同的局域网上。 – Allen 2012-01-17 15:07:03

1

一个简单的解决方案,穿越到NAT路由器的是让你的流量遵循的协议,你的NAT已经有一个转发算法,比如FTP。