请详述TCP穿透NAT的原理

lisd138 2010-04-24 03:26:34
请详述TCP穿透NAT的原理,百度Hi、阿里旺旺的文件传输使用基于TCP的P2P技术,哪个超级高手能详述一下TCP穿透NAT的原理?有具体实现代码的将给120分(网上搜索的那份代码不行,我试验过了).
...全文
1626 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
LeeHGMaster 2011-11-23
  • 打赏
  • 举报
回复
http://dl2.csdn.net/down4/20070724/24133943521.rar
不能下载了,哪位给个连接
danscort2000 2010-04-28
  • 打赏
  • 举报
回复
SKYP用的是UDP
TCP那个DEMO
恐怕只有作者自己的网络能实现穿透
在INTERNET上两端
能穿透的概率估计连作者自己都没测试过
wxxloveu 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 lisd138 的回复:]
请详述TCP穿透NAT的原理,百度Hi、阿里旺旺的文件传输使用基于TCP的P2P技术,由此可见TCP穿透NAT的P2P技术是可行的,哪个超级高手能详述一下TCP穿透NAT的原理?有具体实现代码的将给120分(网上搜索的那份代码不行,我试验过了).本人在做P2P聊天软件.
[/Quote]
原理就不讲了,网上有很多,真的需要的话去我的资源看看,貌似我以前写过一个可以聊天的,自己测试过,在我的公司(内网)可以用我写的软件和我同学(另外一个内网)聊天
http://download.csdn.net/source/1859912
cqsfd 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 wxxloveu 的回复:]

真是羡慕你,有时间和条件继续研究这个,我从去年11月到现在都没碰过这个 了,唉,现在在怀疑自己是不是走错路了
[/Quote]

呵呵 所以这边钱少还累 我也不舍得跳啊
不论做什么 钻下去就好 不用怀疑自己的
wxxloveu 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 cqsfd 的回复:]
进来学习
哪位牛人可以介绍下提高打洞成功率的方法?skype那种流氓方法不算
开贴100分相赠 拜谢
[/Quote]
真是羡慕你,有时间和条件继续研究这个,我从去年11月到现在都没碰过这个 了,唉,现在在怀疑自己是不是走错路了
zhou1xp 2010-04-26
  • 打赏
  • 举报
回复
学习一下
Eleven 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 cqsfd 的回复:]
听高手说的,自己没研究过skype的代码。skype让打洞成功的某个客户A端作为临时服务器,帮忙转发不能打洞的客户端B和C的信息,以减轻服务器压力...太流氓了
[/Quote]
真的加的??这NX啊
cqsfd 2010-04-26
  • 打赏
  • 举报
回复
听高手说的,自己没研究过skype的代码。skype让打洞成功的某个客户A端作为临时服务器,帮忙转发不能打洞的客户端B和C的信息,以减轻服务器压力...太流氓了
sms88 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 cqsfd 的回复:]

进来学习
哪位牛人可以介绍下提高打洞成功率的方法?skype那种流氓方法不算
开贴100分相赠 拜谢
[/Quote]

skype用的什么方法?
尹成 2010-04-25
  • 打赏
  • 举报
回复
实很早我就已经实现了使用TCP协议穿透NAT了,但是苦于一直没有时间,所以没有写出来,现在终于放假有一点空闲,于是写出来共享之。

一直以来,说起NAT穿透,很多人都会被告知使用UDP打孔这个技术,基本上没有人会告诉你如何使用TCP协议去穿透(甚至有的人会直接告诉你TCP协议是无法实现穿透的)。但是,众所周知的是,UDP是一个无连接的数据报协议,使用它就必须自己维护收发数据包的完整性,这常常会大大增加程序的复杂度,而且一些程序由于某些原因,必须使用TCP协议,这样就常常令一些开发TCP网络程序的人员“谈穿透色变”。那么,使用TCP协议是不是就不能实现穿透呢?答案当然是否定的:TCP协议不仅能实现NAT穿透,而且实现起来比UDP穿透甚至还简单一些。


要了解如何使用TCP穿透NAT,就要首先看看如何使用UDP穿透NAT。
我们假设在两个不同的局域网后面分别有2台客户机A和 B,AB所在的局域网都分别通过一个路由器接入互联网。互联网上有一台服务器S。
现在AB是无法直接和对方发送信息的,AB都不知道对方在互联网上真正的IP和端口, AB所在的局域网的路由器只允许内部向外主动发送的信息通过。对于B直接发送给A的路由器的消息,路由会认为其“不被信任”而直接丢弃。
要实现 AB直接的通讯,就必须进行以下3步:A首先连接互联网上的服务器S并发送一条消息(对于UDP这种无连接的协议其实直接初始会话发送消息即可),这样S就获取了A在互联网上的实际终端(发送消息的IP和端口号)。接着 B也进行同样的步骤,S就知道了AB在互联网上的终端(这就是“打洞”)。接着S分别告诉A和B对方客户端在互联网上的实际终端,也即S告诉A客户B的会话终端,S告诉B客户A的会话终端。这样,在AB都知道了对方的实际终端之后,就可以直接通过实际终端发送消息了(因为先前双方都向外发送过消息,路由上已经有允许数据进出的消息通道)。


用UDP来实现以上3步不存在什么理论上的问题,因为UDP是无连接的协议,它允许socket进行“多对一”的通讯(即几个具有不同IP和端口号的socket向一个接收socket发送消息)。但是使用TCP就出现了问题:在一般情况下,TCP socket不允许在已经建立连接的端口上再进行监听和使用该本地端口。换句话说,当AB连接上服务器S后,S将AB的实际终端告诉对方,下一步本该是AB利用对方的实际终端进行直连,但这时你会发现对方的实际终端已经被占用了(就是各自连接到服务器S的会话占用了终端),无法同时listen和 connect。于是很多人得出结论:TCP无法实现NAT穿透。
于是问题的关键变成了如何复用一个TCP连接的本地终端,这其实不是协议的问题,而是一个API的问题。幸运的是,所有主流操作系统都支持一个特定的TCP套接字选项——SO_REUSEADDR。这个选项允许将多个socket绑定到同一个本地终端。我们建立socket的时候只要加上这么一行:

setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &flag, len) ; //C++就这么做

_Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, True) '这是vb.net 更加简单
知道上面的知识就很好办了,下面我来说说TCP协议的穿透流程:
机器布局还是和上面使用UDP的一样。现在假设客户A想和客户B建立TCP连接。
首先还是 AB分别和服务器S分别建立连接,S记录AB的互联网实际终端。然后S分别向AB发送对方的实际终端。接着,从A和B向S连接时使用的端口,AB都异步调用connect函数连接对方的实际终端(就是S告诉的终端),同时,AB双方都在同一个本地端口监听到来的连接(也可以先监听,再connect更好)。由于双方都向对方发送了connect请求(假设各自的SYN封包已经穿过了自己的NAT),因此在对方connect请求到达本地的监听端口时,路由器会认为这个请求是刚刚那个connect会话的一部分,是已经被许可的,本地监听端口就会用SYN-ACK响应,同意连接。这样,TCP穿透NAT的点对点连接就成功了。

下面是示例代码下载,VB.NET代码,演示如何用TCP协议穿透NAT实现文件传送,请用vs2005打开解决方案

http://dl2.csdn.net/down4/20070724/24133943521.rar

代码中有一个我自己封装的模仿vb6 winsock的控件ZXMSocket,这个socket可以让你设置是否使用SO_REUSEADDR参数,socket是事件驱动的。

如果你要测试代码,需要使用一个bat来启动发送和接收程序(文件格式请参照bin/Debug文件夹下的run.bat文件),这个bat的功能是以命令行的方式告诉程序登录服务器缩使用的用户名,对于服务器来说,这个用户名必须是唯一的,当然,这可能有点不科学,但是这毕竟只是一个demo。
cqsfd 2010-04-25
  • 打赏
  • 举报
回复
进来学习
哪位牛人可以介绍下提高打洞成功率的方法?skype那种流氓方法不算
开贴100分相赠 拜谢
Eleven 2010-04-24
  • 打赏
  • 举报
回复
http://www.cnblogs.com/regedit/articles/829725.html
lisd139 2010-04-24
  • 打赏
  • 举报
回复
摘要
防火墙和网络地址转换(NAT)设备对于传统的P2P协议存在一定的问题。一些中间设备抑制了来自外部网络到内部网络的TCP请求,这篇文章的目的就是寻找一个能够在两个NAT设备内部的主机间建立TCP连接的方法。我们已经在两个普通的硬件条件下实现了这个功能。
1.入门
由于32位IP地址的减少,现在出现了很多通过一个internet地址代理内部网络上网的设备,这就是NAT技术。这些设备对于INTERNET已经越来越重要了,但是它们的独立发展因为缺乏标准而对现在的internet协议造成危害。
2.技术
典型的NAT和防火墙设备都是不允许外部地址主动请求而进入内部网络的,如果用户的程序需要在两个内部网络间建立直接性的连接,那
么两个内部设备之间必须是相互信任的。如果A和B两个部分都初始化了TCP连接,NAT设备就会认为它们之间是相互信任的,也就允许它们之间的连接了。
图1是一个例子,目标是能够让A和B(分别在NATA和NATB后)建立TCP连接。
我们讨论了多种在特定的NAT设备环境下的TCP连接方案。
如果我们的情况如下:
1、可预测NA的端口,可预测NB的端口,可指定源IP的特定路由
2、可预测NA的端口,可预测NB的端口,不可指定源IP的特定路由
3、随机的NA端口,可预测NB的端口,可指定源IP的特定路由
4、随机的NA端口,可预测NB的端口,不可指定源IP的特定路由
5、随机的NA端口,随机的NB端口,可指定源IP的特定路由
6、随机的NA端口,随机的NB端口,不可指定源IP的特定路由
我们必须作出这4种假设:
1、 两个主机都不受NAT设备所限制;
2、 我们可以配置网络设备使得主机看不到来自外部网络的
ICMP包(TTL超过限制),因为这些ICMP数据包无论被任何一方接收到都是中断TCP连接。我们讨论的一些解决方案就依赖通过发送一个初始TTL很
小的SYN包来建立TCP连接。一旦SYN包被路由器丢弃,ICMP TTL
超时包就会被传送到NAT设备,我们不允许NAT设备将这个超时TTL的返回包传送到内部网络,即使NAT会将这个包传送到内部,也需要通过配置防火墙来
限制这个包到达主机;
3、 即使NAT设备看到ICMP超时的数据包,设备本身的映射表将不会作任何改动;
4、 内部网络的其它主机不会占用抢占这个端口,因为如果网络特别繁忙,这个端口可能会无效。
3.1第一种情况
我们可以通过图2表示的顺序解决问题:
1)A和B可以设定LSR(IP报头中的一个选项)通过X路由发送SYN数据包.
2)X可以缓存它们的数据包并且发送欺骗的SYN+ACKS给NA和NB.
3)A和B可以通过由X发送来的数据进行应答.
4)X丢弃这两个ACK包,因为它已经可以确定A和B相互应答成功.



图2是假设A和B都事先彼此的NAT的通信端口,A知道B的通信端口是NB:5000,B知道A的是NA:4000,并且要求X不在任何NAT设备的后面.实际中这两个端口是预测得到的,预测过程如图3:


3.2第二种情况

一种情况依赖与自由设定路由,但是现在很多路由器大多都限制这样做,并且会丢弃这样的服务请求包。因此在实际应用中,这种方案失败的可能性很大。如果自由
设定路由不可行,我们可以通过out-of-band通道(他们预先与X连接好的TCP连接)来传送原本必须将数据包路由到X才能看到的包。注意在图二的
第二步X已经知道了TCP的序号Q和P,因为X已经收到了这两个SYN包,但是如果数据包没有路由经过X就不可能收到它们。为了初始化这个连接,两个主机
发送初始SYN包,并且他们都知道是不可能到达目标的,但是它们都可以记住自己的SYN号(个人看法,通过钩子获得发送的数据SYN包)并且可以发送给
X,X得到了它们的SYN包,就可以欺骗它们发送ACK包了。有两种方法可以发送无法到达目标的数据包。简单的方法就是每个主机发送一个SYN给对方,要
求应答包不会到达内部网络.如果NAT(防火墙)会将应答包传回给内部网络,通常是发送TCP的reset包(RST),如果NAT生成RST包,A和B
就不能简单地发送一个向图2中SYN给彼此,因为如果这样NA和NB就无法打洞了呵呵,如果NAT不发送RST包,那么这个TCP连接就不会被中断。另外
一个发送无法到达目标网络的SYN包的方法是减小TTL值,使它们无法彼此到达。如果用户无法配置防火墙丢弃这个ICMP应答包,或者NAT不继续传送这
个ICMP,这个TCP就不会立即关闭。这个解决方案不能使用一种简单的欺骗,因为我们必须保证源地址的SYN包发送者不会没有收到ICMP的RST包,
否则会导致中间设备建立错误路由.仅仅依靠SYN包,NAT就可以建立从internet
IP和端口到外部IP和端口的路由.由于欺骗的SYN包是错误的源IP(并非发出者X),这个路由将不会发送到X而是发送到NA或者NB。另外,这种方案
都需要设置TTL到足够小,以便于对方的NAT不会收到到各自发出的初始SYN包,否则就无法完成打洞。(图4)

3.3第三种情况
比前两种简单,但是X将无法预见NA或者NB的端口。B将先给X发送一个SYN包告诉以便于X知道它所选用的端口号,然后X将这个信息发送到A,A就可以向这个确定的地址和端口发送SYN,图5是第一种情况的变形::
1)X向图3一样预测端口,但是它不能预测到NA的下一个端口号,但是可以预测NB的下一个端口号是5000,并且可以通知A和B这个节点已经建立了连接;
2)A和B同步节点X;
3)X可以欺骗A和B;
4)A和B相互发送ACK;
5)X丢弃发给它的ACK,因为它已经可以确认它们已经建立连接。
liruda 2010-04-24
  • 打赏
  • 举报
回复
请看http://www.vckbase.com/document/viewdoc/?id=1773
lisd138 2010-04-24
  • 打赏
  • 举报
回复
请详述TCP穿透NAT的原理,百度Hi、阿里旺旺的文件传输使用基于TCP的P2P技术,由此可见TCP穿透NAT的P2P技术是可行的,哪个超级高手能详述一下TCP穿透NAT的原理?有具体实现代码的将给120分(网上搜索的那份代码不行,我试验过了).本人在做P2P聊天软件.

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧