使用TCP协议的NAT穿透技术

实很早我就已经实现了使用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。 

时间: 2025-01-27 00:04:12

使用TCP协议的NAT穿透技术的相关文章

TCP协议通讯流程

    服务器调用socket().bind().listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服务器应答,服务器应答一个SYN-ACK段,客户端收到后从connect()返回,同时应答一个ACK段,服务器收到后从accept()返回. 数据传输的过程: 建立连接后,TCP协议提供全双工的通信服务,但是一般的客户端/服务器程序的流程是由客户端主动发起请求,服务器被动处理请求,一问一答

用C#实现基于TCP协议的网络通讯

网络 TCP协议是一个基本的网络协议,基本上所有的网络服务都是基于TCP协议的,如HTTP,FTP等等,所以要了解网络编程就必须了解基于TCP协议的编程.然而TCP协议是一个庞杂的体系,要彻底的弄清楚它的实现不是一天两天的功夫,所幸的是在.net framework环境下,我们不必要去追究TCP协议底层的实现,一样可以很方便的编写出基于TCP协议进行网络通讯的程序. 要进行基于TCP协议的网络通讯,首先必须建立同远程主机的连接,连接地址通常包括两部分--主机名和端口,如www.yesky.c

用C#实现基于用C#实现基于TCP协议的网络通讯

网络 TCP协议是一个基本的网络协议,基本上所有的网络服务都是基于TCP协议的,如HTTP,FTP等等,所以要了解网络编程就必须了解基于TCP协议的编程.然而TCP协议是一个庞杂的体系,要彻底的弄清楚它的实现不是一天两天的功夫,所幸的是在.net framework环境下,我们不必要去追究TCP协议底层的实现,一样可以很方便的编写出基于TCP协议进行网络通讯的程序. 要进行基于TCP协议的网络通讯,首先必须建立同远程主机的连接,连接地址通常包括两部分--主机名和端口,如www.yesky.c

c++-如何用重写TCP协议,或者修改ws2_32.dll文件

问题描述 如何用重写TCP协议,或者修改ws2_32.dll文件 做通信专业本科毕业设计,老师希望建立卫星通信的仿真演示系统.其中比较重要的是进行不同传输协议的比较.由于空间环境不能使用地面TCP,要改用空间TCP或其他传输协议.可能是要修改电脑的网络传输相关的库文件,根本不会!求救!! 另外,前期利用MFC完成了大部分的演示工作. 解决方案 可以使用raw sockethttp://blog.csdn.net/kzm2008/article/details/5372834 解决方案二: 建议你

《趣学CCNA——路由与交换》一第2章 TCP/IP协议2.1 TCP协议简介

第2章 TCP/IP协议 趣学CCNA--路由与交换 在上一章,我们郑重其事地介绍了无聊的OSI七层参考模型,并浓墨重彩地讲述了其中每一层负责提供的功能.OSI模型出身名门.条理清晰,只有一个"小小的"缺点,那就是一直没人太拿它当回事儿.所以,如果对它太认真,你就败了. 我们是有职业精神的,因此在介绍OSI模型时反复强调了这个模型是如何地曲高和寡.我们在上一章中花大篇幅介绍OSI模型有三个目的:一是延续各类技术教材的惯例,以免将本书作为技术开蒙读物的读者在与别人讨论技术问题时,因全然不

PJNATH介绍 -- 开源的用于NAT穿透的ICE, STUN和TURN

原文地址:http://blog.pjsip.org/2007/04/06/introducing-pjnath-open-source-ice-stun-and-turn/ ICE是什么? 对于那些不熟悉ICE的人而言,ICE可能是一种最全面的用于穿透NAT和多媒体通信的方法.它提供了一种找到两个终端之间最好路径的方法,它还解决了NAT所带来的各种各样的问题,比如两个终端处在同一个NAT后面(and no hairpin is available),两个终端都处在对称NAT后面(在这种情况下,

升级TCP协议使将网速提升30% 中国受益尤为明显

北京时间1月25日午间消息,美国CDN(内容分发网络)巨头Akamai近期宣布,计划通过新技术对内容进行大幅提速,从而带来更快的下载速度,以及更可靠.质量更高的流媒体视频服务. 在全球范围内,Akamai运营着超过20万台服务器.ISP(互联网服务提供商)和类似Facebook的企业利用这些服务器去传输数据.上周四,Akamai公布了代号为"Giga"的新技术的测试结果.在测试中,通过新技术,数据传输速度平均要比当前高30%. 在Facebook举办的流媒体视频技术大会上,Akamai

协议系列之TCP协议

3.TCP协议 从上一节我们了解了什么是IP协议,以及IP协议的一些特性,利用IP协议传输都是单向的,不可靠的,无连接状态的.正是这些特性,于是便产生了TCP协议.TCP协议属于传输层,在IP协议网络层之上,竟然IP协议不可靠,那就必须要在其上多一个TCP协议以实现传输的可靠性.就像我们寄出一封信,如果对方不回信,不通过别的渠道告诉你,你永远都无法保证这封信能准确送到对方手上.同样,TCP协议采取了类似的措施来保证数据包的准确送达,它规定接收端发送一个确认数据包回来. 严格地说,TCP协议提供了

升级TCP协议网速提升30%:中国受益明显

据外媒报道,美国CDN巨头Akamai宣布,计划通过新技术对内容进行大幅提速,从而带来更快的下载速度,以及更可靠.质量更高的流媒体视频服务. Akamai公布了代号为"Giga"的新技术的测试结果.在测试中,通过新技术,数据传输速度平均要比当前高30%.Akamai媒体工程副总裁吉特·诺克斯(Kit Knox)表示,该公司希望这项技术能够成为标准. Akamai动用了遍布全球的服务器去进行这项测试.由于位置和各地ISP的不同,测试结果也有所不同.不过平均来看,数据传输速度提升了30%.