您的位置:首页 > 其它

P2P技术-UDP hole punching

2015-08-14 14:54 288 查看
UDP Hole Punching的主要思想是:利用一个任何客户端都可达的服务器,在服务器上事先存储、维护客户端的UDP公用端点地址,当双方需要通信时,可以通过服务器的“介绍”获取对方的端点地址,建立“直接”的连接。

图1是一个具有NAT设备的简单网络拓扑图,其中C1,C2位于不同的私有网络中,无法直接通信,但都可以访问Server。下面分析UDP Hole Punching的基本流程:

(1)C1向服务器发出请求,要求与C2建立连接。

(2)服务器向C1,C2发送对方的公用端点地址,公用端点地址是服务器根据C1,C2发送的UDP数据报的源端点地址“观察”到的,即NAT设备“翻译”后的端点地址。

(3)C2接收到C1 的端点地址后,考虑到其所处网络的NAT设备可能具有防火墙功能,利用C1的端点地址作为目的地址,发送“穿洞”UDP数据报,该数据报使得C2网络的NAT设备允许后续的以C1端点地址为源地址的UDP数据报进入其内部网络,像是在NAT设备的防火墙上“穿洞”,对以C1端点地址为源地址的UDP数据报开放“入口”。

(4)C1接收到C2 的端点地址后,以C2的端点地址为目的地址发送“探测”UDP数据报,同样该数据报也使得C1网络的NAT设备上形成“穿洞”。

(5)C2收到C1的“探测”数据报后,向C1发送确认数据报。至此,双方建立互通的UDP连接。

在(2)中,考虑到C1、C2可能处于同一个私有网络中,服务器可以同时发送私有、公用端点地址,然后C1、C2先尝试使用对方私有端点地址进行通信,失败的情况下,再使用公用端点地址。



图1

需要指出的是,并不是任何的NAT设备都支持这上述的“穿透”过程。一个“友好”的NAT设备必须是“非对称”的:客户端的私有端点地址被NAT设备“翻译”成公用端点地址后,客户端再使用此私有端点地址向其它目的端点地址发送数据报,NAT设备并不会因为目的端点地址的改变而改变映射的公用端点地址,否则,C1、C2获取的对方端点地址因为“映射”改变而失效。同时,对于复杂的具有多层NAT设备的网络环境,NAT设备也需提供
“回环转换”的功能:NAT设备接收来自内部网络的数据报,但是目的端点地址却是其原先“对外”映射的公用端点地址,此时NAT设备仍可以“回环”的把目的端点地址“翻译”成内部网络端点地址,并把数据报转发回内部网络。

3 基于UDP Hole Punching的实现




图2
本文基于.Net框架开发一个轻量级的面向对象类库,完整的实现UDP Hole Punching 的穿透过程。图2是类库(灰底框)分层结构,描述了类库边界以及体系结构。其中NAT Client/Server API 层是类库对外提供的服务器与客户端的编程接口;NAT Traversal Layer是整个类库的核心,处理UDP Hole Punching过程中的各种情境,建立客户端之间“直接”连接等;Asynchronous
UDP Socket是基于UDP的异步收发套接字,为上下层收发数据。

图3是整个实现的部分类图(限于篇幅省略了方法与属性)。下面是部分类功能的简单描述:

(1)客户端:NATClient 是客户端的用户接口,负责客户端的登陆、登出,向下层转发字节形式的用户数据,同时向上层传递接收到的用户数据;ConnectionManager是整个客户端的核心,它是客户端多个UDP套接字的管理器,负责启动穿透过程,接收来自其它客户端、服务器的各种消息以及作出相应响应。MessageBufferQueue与QueueWithTimer是发送到其它客户端的用户数据缓存区,放入缓存区内的数据如果在一个很小的时间间隔内还没发送出去,将通知客户端发送失败。NATSessionManager与NATSession负责管理其它客户端的端点地址(包括客户端的私有、公用端点地址);RegisterUtility具有向服务器注册本地UDP套接字的功能,它能探测出客户端到服务器之间NAT设备的端点地址映射保持时间长短,动态调整UDP套接字注册间隔,从而减少客户端、服务器的负担。

(2)服务器:NATServer负责客户端消息的处理,比如注册消息,请求客户端的端点地址,通知客户端准备接收来自其它客户端的用户数据等;ClientMapTable 与SocketMapItem 存放、管理客户端注册的UDP套接字端点地址。

(3) 其它:根据UDP Hole Punching穿透过程中的各种情境,需要定义多种的消息类型,具有各自的消息负载格式,表1是各种消息类功能说明。



[align=center]图3[/align]
[align=center]表1[/align]

[align=center]RegORUnReg[/align]
客户端向服务器端发送的UDP套接字注册、取消注册消息。
[align=center]1)SendUserData[/align]
[align=center]2)RelayUserData[/align]
1)上层的用户数据消息。2)中转消息:客户端之间无法“直接”通信时,可以通过服务器中转的用户数据消息。
[align=center]1)RequsetEndPoint[/align]
[align=center]2)ReplyEndPoint[/align]
1)客户端请求服务器提供客户端端点地址消息。
2)服务器提供客户端端点地址消息。
[align=center]1)ProbeReceiver[/align]
[align=center]2)ACKSenderProbe[/align]
1)客户端探测目的客户端是否可达的消息;
2)目的客户端确认发起客户端探测可达消息。
[align=center]RequestToReceive[/align]
服务器要求客户端准备接收来自其它客户端用户数据消息。
[align=center]ReceiverPunching[/align]
客户端“穿洞”消息。
[align=center]ReduceRegisterSpan[/align]
服务器要求客户端减少UDP套接字的注册间隔时间。
4 结束语

现实的网络环境中,NAT是一个普遍存在现象,基于P2P通信的应用程序要求参与客户端的通信对等性,造成多数通信终端无法“直接的”收发数据,因此NAT穿透是基于P2P通信的应用系统必须首要解决的问题。目前,由于NAT设备的多样性,还没有一种技术可以“完全”有效解决NAT穿透过程中的各种问题,因此一个健壮的基于P2P通信的系统,需要结合运用多种穿透方法,使得通信终端可以畅通无阻的进行“交流”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: