TCP打孔

时间:2012-01-11 12:20:24

标签: windows tcp network-protocols winsock2 hole-punching

我正在尝试使用mingw工具链实现使用Windows套接字的TCP打孔。我认为这个过程是正确的,但 hole 似乎没有。我使用this作为参考。

  1. A B 连接到服务器 S
  2. S 发送到 A B 的路由器IP +用于连接 S 的端口
  3. S B
  4. 执行相同操作
  5. A 启动2个主题:
    • 一个主题尝试使用 S
    • 发送的信息连接到 B 的路由器
    • 当另一个线程连接到 S
    • 时,正在等待连接到其路由器的同一端口上的传入连接
  6. B 执行相同的操作
  7. 我认为代码中没有任何问题:

    • A B 确实互相使用ip和端口
    • 当他们联系服务器时,他们都在监听他们用来连接路由器的端口
    • 他们都连接到正确的IP和端口但是超时(代码错误10060

    我遗失了什么?

    编辑:在进程资源管理器的帮助下,我看到其中一个客户端设法与对等方建立连接。但是同伴似乎并没有考虑要建立联系。

    这是我用Wireshark捕获的内容。为示例,服务器 S 和客户端 A 位于同一台PC上。服务器 S 侦听重定向到该PC的特定端口(8060)。 B 仍尝试连接正确的IP,因为它看到 S 发送的 A 的公开地址为localhost,因此使用 S 的公共IP代替。 (我已经用占位符替换了公共IP)

    wireshark

    编辑2 :我认为混淆是由于传入和传出的连接请求数据都在同一端口上传输。这似乎弄乱了连接状态,因为我们不知道哪个套接字将从端口获取数据。如果我引用msdn:

      

    SO_REUSEADDR套接字选项允许套接字强制绑定到a   另一个套接字使用的端口。第二个套接字调用setsockopt   optname参数设置为SO_REUSEADDR和optval参数集   在调用与之相同的端口上的bind之前,将布尔值设置为TRUE   原装插座。 第二个套接字成功绑定后,即可   绑定到该端口的所有套接字的行为是不确定的。

    但TCP Hole Punching技术需要在同一个端口上进行交谈才能打开漏洞

4 个答案:

答案 0 :(得分:12)

  

开始2个主题:
      一个线程尝试使用S
发送的信息连接到B的路由器       另一个线程在连接到S
时用于连接到路由器的同一端口上等待传入连接

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

但是,您可能需要关闭与服务器的连接。当您已经从同一端口建立了连接时,您的平台可能不允许您从端口建立TCP连接。因此,就像启动TCP打孔一样,关闭与服务器的连接。将新的TCP套接字绑定到同一端口,然后调用connect

答案 1 :(得分:1)

遍历NAT路由器的一个简单解决方案是使您的流量遵循NAT已经具有转发算法的协议,例如FTP。

答案 2 :(得分:0)

  1. 使用Wireshark检查tcp连接请求(3路Handhsake过程)是否正常。

  2. 确保您的Listener线程正在使用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. 5.确保您同时启动对等连接A到B和B到A. 6.在连接到服务器和Peer之前启动监听器线程,并使用单个侦听器线程接收服务器和客户端。

答案 3 :(得分:-3)

并非每个路由器都支持tcp打孔,请查看以下详细说明的文件:

Peer-to-Peer Communication Across Network Address Translators