一直以来,说起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的点对点连接就成功了。
分享到:
相关推荐
3. **NAT穿透原理**:由于NAT的存在,两个内网设备直接通信变得复杂。NAT穿透技术(如STUN、TURN、ICE)旨在让这些设备通过第三方服务器进行间接通信,服务器作为中介,传递设备之间的IP和端口信息,从而建立直接...
2. NAT穿透原理: - 非对称NAT:当内网设备通过NAT对外发起连接时,NAT会分配一个临时的公网端口,这导致从外部回连时,公网IP和端口可能不同,形成穿透难题。 - STUN(简单Traversal of NAT):一种发现NAT映射...
1. 非对称NAT穿透:在非对称NAT中,出站和入站规则不同,因此需要两步建立连接。首先,客户端A通过服务器B向客户端B发送一个带有其公网IP和端口的UDP数据包。客户端B收到后,通过自己的NAT向A的公网IP和端口发送响应...
NAT穿透是解决在私有网络(局域网)中的计算机与外部网络进行通信时,由于网络地址转换(NAT)设备的存在,使得外部网络无法直接访问内部网络设备的问题。这个问题在对等网络(P2P)通信模式中尤为突出,尤其是在...
文档可能包含对NAT工作原理的解释、XMPP协议的详细描述,以及如何利用Jingle和NAT穿透技术来优化通信性能的实例。这些内容对于理解XMPP在复杂网络环境下的应用,以及开发相关通信软件都是非常有价值的参考资料。
了解这些不同类型的NAT的特点及其工作原理对于成功实现NAT穿透至关重要。 #### 不同类型的NAT 1. **Full Cone NAT(完全圆锥型NAT)** - **特点**:当内部主机首次通过UDP Socket发送数据到外部主机时,NAT会为...
综合这些资源,你可以深入了解NAT的工作原理,学习如何利用TCP和UDP进行NAT穿透,以及在实际的P2P系统中如何实现这些技术。这些资料对于网络编程、P2P应用开发或者网络通信研究者来说都是宝贵的学习材料。
本文将深入探讨NAT穿透的基本原理以及提供的源代码。 NAT是一种普遍应用于家庭和企业网络的技术,它允许一个或多个设备共享一个公共IP地址,同时通过内部网络的私有IP地址进行通信。然而,这种设置使得直接的P2P...
2. ICE框架:ICE是一种更全面的NAT穿透机制,结合了STUN和TURN(Traversal Using Relays around NAT)服务器。TURN服务器作为中继,当两台设备无法直接通信时,它们可以通过中继服务器转发数据。ICE会尝试各种可能的...
NAT穿透通常有两种方法:STUN(简单Traversal of UDP through NAT)和ICE(Interactive Connectivity Establishment)。STUN服务器提供了一个公开的IP和端口,使内网设备能够发现自己的NAT类型和外网映射。ICE则是一...
总之,P2P之UDP穿透NAT的实现涉及到网络编程、NAT工作原理以及UDP协议的特性。通过代码实现,可以学习到如何在实际环境中克服NAT对P2P通信的障碍,这对于开发分布式系统和实时通信应用具有重要意义。
UDP(User Datagram Protocol)是一种无连接的传输层协议,它提供了快速、简单、不可靠的数据报服务。在处理网络通信时,NAT(Network ...通过理解这些原理和Java中的实现细节,你可以构建自己的NAT穿透解决方案。
源代码通常会包含上述步骤的实现,包括套接字编程、STUN/TURN协议的处理以及NAT穿透策略的逻辑。对于初学者来说,理解并分析这些代码可以帮助深入理解P2P网络和UDP穿透NAT的工作原理。 总之,P2P中的UDP穿透NAT是...
NAT穿透技术是一种在网络地址转换(Network Address Translation)环境下实现设备间通信的...通过理解NAT穿透的基本原理和MFC的特性,开发者可以进一步优化这个程序,提高其稳定性和适应性,为更多应用场景提供服务。
P2P 之 UDP穿透NAT的原理与实现(附源代码)
**NAT穿透内网技术详解*...通过学习和理解NAT穿透的原理以及相关源代码,我们可以更好地理解和解决网络通信中的各种问题,提高网络应用的效率和可靠性。对于初学者来说,这份资料和源代码是深入理解NAT穿透的宝贵资源。
NAT穿透,又称为端口映射或者打洞技术,是为了让两个位于NAT后的设备能够直接通信而设计的一种技术。 NAT的工作原理是将内部网络中的私有IP地址与外部网络的公共IP地址进行映射,这样内部网络的设备可以通过一个...
P2P 之 UDP穿透NAT的原理与实现
UDP(User Datagram Protocol)是一种无...对于学习网络编程和理解NAT穿透原理的开发者来说,这是一个非常有价值的资源。通过深入研究和实践,可以掌握如何在C#环境中实现可靠的UDP通信,以及如何处理NAT环境中的挑战。