我摘录网上流行的一篇文章,标题是《TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞》,我逐一分析他的打洞描述:原文:1、 S启动两个网络侦听,一个叫【主连接】侦听,一个叫【协助打洞】的侦听。  2、 A和B分别与S的【主连接】保持联系。   3、 当A需要和B建立直接的TCP连接时,首先连接S的【协助打洞】端口,并发送协助连接申请。同时在该端口号上启动侦听。注意由于要在相同的网络终端上绑定 到不同的套接字上,所以必须为这些套接字设置 SO_REUSEADDR 属性(即允许重用),否则侦听会失败。4、 S的【协助打洞】连接收到A的申请后通过【主连接】通知B,并将A经过NAT-A转换后的公网IP地址和端口等信息告诉B。  5、 B收到S的连接通知后首先与S的【协助打洞】端口连接,随便发送一些数据后立即断开,这样做的目的是让S能知道B经过NAT-B转换后的公网IP和端口号。   6、 B尝试与A的经过NAT-A转换后的公网IP地址和端口进行connect,根据不同的路由器会有不同的结果,有些路由器在这个操作就能建立连接(例如我 用的TPLink R402),大多数路由器对于不请自到的SYN请求包直接丢弃而导致connect失败,但NAT-A会纪录此次连接的源地址和端口号,为接下来真正的连 接做好了准备,这就是所谓的打洞,即B向A打了一个洞,下次A就能直接连接到B刚才使用的端口号了。  7、 客户端B打洞的同时在相同的端口上启动侦听。B在一切准备就绪以后通过与S的【主连接】回复消息“我已经准备好”,S在收到以后将B经过NAT-B转换后的公网IP和端口号告诉给A。   8、 A收到S回复的B的公网IP和端口号等信息以后,开始连接到B公网IP和端口号,由于在步骤6中B曾经尝试连接过A的公网IP地址和端口,NAT-A纪录 了此次连接的信息,所以当A主动连接B时,NAT-B会认为是合法的SYN数据,并允许通过,从而直接的TCP连接建立起来了。

解决方案 »

  1.   

    我只分析关键的描述:[color=#FF00]
    4.S的【协助打洞】连接收到A的申请后通过【主连接】通知B,并将A经过NAT-A转换后的公网IP地址和端口等信息告诉B。 
    [/color] 

    这个所谓转换后的公网IP和端口,实际上是和服务器的那个连接的端口,这个端口是否就是一个洞,它是否接受不同IP的连接呢?事实是,我试验,它根本不接受connect连接。
     
    [color=#FF00]
    5、 B收到S的连接通知后首先与S的【协助打洞】端口连接,随便发送一些数据后立即断开,这样做的目的是让S能知道B经过NAT-B转换后的公网IP和端口号。 
    [/color] 

    我不知道,他为什么要发送一些数据,事实上,只要连接就知道IP和端口来,没有必要发送数据。
     
    [color=#FF00]
     7、 客户端B打洞的同时在相同的端口上启动侦听。B在一切准备就绪以后通过与S的【主连接】回复消息“我已经准备好”,S在收到以后将B经过NAT-B转换后的公网IP和端口号告诉给A。 8、 A收到S回复的B的公网IP和端口号等信息以后,开始连接到B公网IP和端口号,由于在步骤6中B曾经尝试连接过A的公网IP地址和端口,NAT-A纪录 了此次连接的信息,所以当A主动连接B时,NAT-B会认为是合法的SYN数据,并允许通过,从而直接的TCP连接建立起来了。 
    [/color] 

    7所谓的NAT-B的公网IP和端口还是和S连接的端口,但是TCP每个连接都有一个新的端口,同样一个对S的洞,是否能够被别的IP使用呢?
    总之,这个文章的核心操作技术双方发起连接的端口,都是连接服务器的那个连接外网端口,我试验的结果是根本行不通。
     
      

  2.   

    甚至对于比较简单的情况,一个内网对一个公网IP,公网发出对内网的连接请求都不响应。一个内网的计算机A对服务器S发起一个连接,我们称为socketAS,连接成功,S得到A的外网IP和端口,这里注意,每个连接,这个端口是不同的。如果服务器针对这个端口发送connect,根本就连不上,即使A已经启动了针对socketAS本地端口上的监听。如果A有发起一个连接socketAS2,但是使用不同的端口,如果服务器响应这个连接,那么和第一个情况相同,没有意义。如果服务器不响应这个连接,而是发起一个针对它的connect,能否成功呢?问题是,不响应的话,socketAS2的外网端口又无从知道。
      

  3.   

    WINDOWS自带的FTP客户端程序的send命令就是让服务器反向连接
    =======================================================
    FreeLaxy, your backup.
    =======================================================
      

  4.   

    p2p模型中的服务器,看起来不就是一个代理服务器吗?但是这个代理只服务一件事情就是告知对方的ip和端口。
      

  5.   

    这个可能要涉及到路由器上的NAT连接生存周期,比如TCP,UDP老化时间。
      

  6.   

    这哥们像个大尾巴狼一样, 发N个帖也不结贴, 看来不让他掏点RMB, 对不起他.
      

  7.   

    1500 RMB, 或者200USD,帮你搞定, 保住你饭碗. 让你摆脱2P的困惑,可以达到3P,4P--- NP.高级合理的打洞方式, 保你爽, 多次打洞, 撞洞帮上的几率为0. 价格便宜, 量又足.需要就咪我.不要害羞.
      

  8.   

    我只分析关键的描述:[color=#FF00]
    4.S的【协助打洞】连接收到A的申请后通过【主连接】通知B,并将A经过NAT-A转换后的公网IP地址和端口等信息告诉B。 
    [/color] 这个所谓转换后的公网IP和端口,实际上是和服务器的那个连接的端口,这个端口是否就是一个洞,它是否接受不同IP的连接呢?事实是,我试验,它根本不接受connect连接。Wenxy answer: 不接受连接的原因有多种:1, 对方的网关有防火墙; 2, 对方没有listen(); etc.
     
    [color=#FF00]
    5、 B收到S的连接通知后首先与S的【协助打洞】端口连接,随便发送一些数据后立即断开,这样做的目的是让S能知道B经过NAT-B转换后的公网IP和端口号。 
    [/color] 我不知道,他为什么要发送一些数据,事实上,只要连接就知道IP和端口来,没有必要发送数据。Wenxy answer: 同意,有时为了维持一个tcp连接,需要定时发送保活数据。记得TCP协议里有一个保活定时器,虽然RFC只是建议TCP/IP协议栈实现它。
     
    [color=#FF00]
     7、 客户端B打洞的同时在相同的端口上启动侦听。B在一切准备就绪以后通过与S的【主连接】回复消息“我已经准备好”,S在收到以后将B经过NAT-B转换后的公网IP和端口号告诉给A。  8、 A收到S回复的B的公网IP和端口号等信息以后,开始连接到B公网IP和端口号,由于在步骤6中B曾经尝试连接过A的公网IP地址和端口,NAT-A纪录了此次连接的信息,所以当A主动连接B时,NAT-B会认为是合法的SYN数据,并允许通过,从而直接的TCP连接建立起来了。 
    [/color] 7所谓的NAT-B的公网IP和端口还是和S连接的端口,但是TCP每个连接都有一个新的端口,同样一个对S的洞,是否能够被别的IP使用呢?
    总之,这个文章的核心操作技术双方发起连接的端口,都是连接服务器的那个连接外网端口,我试验的结果是根本行不通。Wenxy answer:TCP打洞是可以的,Internet上的server就是一个中介,把处于LAN里的计算机经过NAT后的公网IP和端口告诉对方,你的试验方法对了吗?在LAN的网关设置对了吗?尝试设置好网关NAT参数,关闭信源、信宿、Gateway上的防火墙试试!失败是成功之母,:).
      

  9.   

    就最简单的情况,一个内网,一个公网的情况,公网如何对内网发起连接,当然TCP的,有人能简单的写几个关键代码吗?我的疑问如下:公网调用connect函数的时候,指定的端口是如何获得的。肯定是来自上一个客户端发起的的连接,那么那个连接是断开还是保持,还是无所谓。这时候,其实是上一次连接同时吧,客户端已经启动了发起连接的本地端口的监听,这种情况下,是否就应该连接成功了。
      

  10.   

    TCP打洞与UDP不同,关键是涉及端口重用
      

  11.   

    ggggggggggggggggggggggggggggggggggggggggggggggg
      

  12.   

    这就是那篇文章代码运行的结果,看来不是我没有理解,而是他确实不适合我的网络,不过我就是普通路由器局域网环境,应该是有代表性的,而且迅雷早我的环境里确实可以建立TCP的客户对客户的连接。
      

  13.   

    那篇文章所说的TCP打洞前提是peers双方的一方是外网IP或者开启UPnP的情况下可以穿透成功!!
      

  14.   

    我想 应该可以实现 现在我们用的QQ中文件传输的原理应该就是TCP打洞。分别在两个不同的局域网的QQ是可以实现文件传输的,文件传输就是用得tcp协议。他们是怎么实现连接的,我感觉应该是用tcp打洞。
      

  15.   

    没试过,不过应该是可以的,google TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞
      

  16.   

    跟具体网络环境有关。现在的路由很多都有维护tcp连接的状态,故tcp穿透几率不高。udp本身信息很少,还是udp穿透更符合实际。