TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞
这个标题用了两个顿号三个名称,其实说得是同一个东西,只是网上有不同的说法罢了,另外好像还有人叫TCP打孔(我的朋友小妞听说后问“要打孔啊,要不要我帮你去借个电钻过来啊?”“~!·¥%……·!”)。
闲话少说,我们先看一下技术背景:
Internet的迅速发展以及IPv4 地址数量的限制使得网络地址翻译(NAT,Network Address Trans2lation)设备得到广泛应用。NAT设备允许处于同一NAT后的多台主机共享一个公网(本文将处于同一NAT后的网络称为私网,处于NAT前的网络称为公网) IP 地址。一个私网IP 地址通过NAT设备与公网的其他主机通信。公网和私网IP地址域,如下图所示:
广域网与私网示意图
一般来说都是由私网内主机(例如上图中“电脑A-01”)主动发起连接,数据包经过NAT地址转换后送给公网上的服务器(例如上图中的“Server”),连接建立以后可双向传送数据,NAT设备允许私网内主机主动向公网内主机发送数据,但却禁止反方向的主动传递,但在一些特殊的场合需要不同私网内的主机进行互联(例如P2P软件、网络会议、视频传输等),TCP穿越NAT的问题必须解决。网上关于UDP穿越NAT的文章很多,而且还有配套源代码,但是我个人认为UDP数据虽然速度快,但是没有保障,而且NAT为UDP准备的临时端口号有生命周期的限制,使用起来不够方便,在需要保证传输质量的应用上TCP连接还是首选(例如:文件传输)。
网上也有不少关于TCP穿越NAT(即TCP打洞)的介绍文章,但不幸我还没找到相关的源代码可以参考,我利用空余时间写了一个可以实现TCP穿越NAT,让不同的私网内主机建立直接的TCP通信的源代码。