下面有4个基本的问答: 问题一:为什么只要可以连上互联网的计算机都可以用QQ相互建立通信,而不需要固定IP? QQ有两种登陆模式 如果上面的东西轻松搞定,那么你可以继续看了,如果不知道,那么下面就不用看了
先贴一点资料 一、登陆。 不管UDP还是TCP,最终登陆成功之后,QQ都会有一个TCP连接来保持在线状态。这个TCP连接的远程端口一般是80,采用UDP方式登陆的时
候,端口是8000。因此,假如你所在的网络开放了80端口(80端口是最常用端口。。就是通常访问Web的端口,禁掉它的话,你的网络对你来说价值已经
不大了),但没有屏蔽腾讯的服务器IP,恭喜你,你是可以登陆成功QQ的。 其实红字部分是不正确的,QQ的文件传输采用的是P2P,也就是为什么在相同局域网下,两个人用QQ传文件会非常快,这里用到的是NAT打洞技术,下面我会详细的说明 无论是传文件还是聊天文字技术上都可以使用P2P,P2P 都可以用UDP实现,而UDP在NAT打洞上面更加方便和成熟,所以腾讯应该是优先UDP,但是使用UDP为了增加可靠性,尤其是传文件,就要用到UDP 模拟TCP ,也就是他所谓的新TCP,看来在UDP安全通信方面,腾讯应该很牛逼了 下面只说的技术,具体QQ是不是这样的只能问腾讯了 (TCP与UDP的打洞技术过程基本相同,支持TCP打洞的nat设备不多,洞其实就是socket,udp和tcp的socket api的问题,具体以后写文章研究一下) * 注:什么是内网、公网 *注:Nat技术基础 NAT(Network Address Translators),网络地址转换:网络地址转换是在IP地址日益缺乏的情况下产生的,它的主要目的就是为了能够地址重用。NAT分为两大类,基本的NAT和NAPT(Network Address/Port Translator)。 最开始NAT是运行在路由器上的一个功能模块。 最先提出的是基本的NAT,它的产生基于如下事实:一个私有网络(域)中的节点中只有很少的节点需要与外网连接(呵呵,这是在上世纪90年代中期提出的)。那么这个子网中其实只有少数的节点需要全球唯一的IP地址,其他的节点的IP地址应该是可以重用的。 另外一种NAT叫做NAPT,从名称上我们也可以看得出,NAPT不但会改变经过这个NAT设备的IP数据报的IP地址,还会改变IP数据报的TCP/UDP端口。基本NAT的设备可能我们见的不多(呵呵,我没有见到过),NAPT才是我们真正讨论的主角。 Client A A是其中的一台计算机,这个网络的网关(一个NAT设备)的外网IP是155.99.25.11(应该还有一个内网的IP地址,比如10.0.0.10)。 如果Client A中的某个进程(这个进程创建了一个UDP Socket,这个Socket绑定1234端口)想访问外网主机18.181.0.31的1235端口,那么当数据包通过NAT时会发生什么事情呢? 首先NAT会改变这个数据包的原IP地址,改为155.99.25.11。 接着NAT会为这个传输创建一个Session(Session是一个抽象的概念, 如果是TCP,也许Session是由一个SYN包开始,以一个FIN包结束。而UDP呢,以这个IP的这个端口的第一个UDP开始,结束呢,呵呵,也许 是几分钟,也许是几小时,这要看具体的实现了)并且给这个Session分配一个端口,比如62000,然后改变这个数据包的源端口为62000。所以本 来是(10.0.0.1:1234->18.181.0.31:1235)的数据包到了互联网上变为了 (155.99.25.11:62000->18.181.0.31:1235)。 一旦NAT创建了一个Session后,NAT会记住62000端口对应的是10.0.0.1的1234端口,以后从18.181.0.31发送到 62000端口的数据会被NAT自动的转发到10.0.0.1上。(注意:这里是说18.181.0.31发送到62000端口的数据会被转发,其他的 IP发送到这个端口的数据将被NAT抛弃)这样Client A就与Server S1建立以了一个连接。 首先如果两个机子全部在外网,也就是他们可以直接相连,那么P2P一点问题也没有 第二如果两个机子一个是内网A,一个是外网B 1.如果内网的主动想外网的请求连接,那么连接就像上面的解释一样 2.但是洞只能有内网来打,洞是有方向性的(session保存这个信息),所以当外网的想主动和内网的连接时,就需要中介服务器,服务器通知内网A向B打洞来建立连接 第三如果两个机子一个是内网A,另一个是另外一个内网B 网络环境描述:
首先让ClientA和ClientB登录到服务器Server(假如两台主机都采用2347端口),此时NAT1和NAT2会分 别为ClientA和 ClientB打开一个指向Server的洞(NAT1上218.7.32.28:26756和NAT2上218.7.31.221:27550)。服务 器应改记录这两个客户端的信息(关键是那两个洞的信息)。当ClientA与ClientB要建立会话时,ClientA首先用2347端口向NAT2的 洞发送一个数据包,当然这个数据包会被NAT2所丢弃,但是由于这是从NAT1内部向外部发送数据,所以NAT1为ClientA打开了一个指向NAT2 的洞。而且这个新洞与原来NAT1上指向Server的旧洞的是同一个洞(因为是同一个端口26756),所以这里可以说这个洞具有了两个方向(关键), 同时指向 Server和NAT2。这时ClientA应该通知Server,告诉ClientB,现在可以向NAT1的那个洞 (218.7.32.28:26756)发送数据包了。当ClientB向NAT1的那个洞发送数据以后,NAT2也为ClientB打了一个指向 NAT1的洞,这是可以说ClientA与ClientB的会话就建立完成了,他们可以不依赖Server进行通信了。如果以后ClientA和 ClientB还需要建立其他会话 ,那么这个牵线的“媒人”可以不是Server,而可以是ClientA或ClientB了。 第四如果两个机子都是同一个内网 用上面的方法肯定可以,那么如果NAT支持loopback(就是本地到本地的转换),A,B可以连接,但是比较浪费带宽和NAT,一般的时候都不会用loopback,会直接内网P2P(我觉得QQ客户端可以做一下判断以选择内网直接P2P) 注: NAT对session的处理 以下分析NAPT是依据什么策略来判断是否要为一个请求发出的UDP数据包建立Session的.主要有一下几个策略: A. 源地址(内网IP地址)不同,忽略其它因素, 在NAPT上肯定对应不同的Session B. 源地址(内网IP地址)相同,源端口不同,忽略其它的因素,则在NAPT上也肯定对应不同的Session C. 源地址(内网IP地址)相同,源端口相同,目的地址(公网IP地址)相同,目的端口不同,则在NAPT上肯定对应同一个Session D. 源地址(内网IP地址)相同,源端口相同,目的地址(公网IP地址)不同,忽略目的端口,则在NAPT上是如何处理Session的呢?(这个要根据下面NAT的种类区别,Cone相同,Symmetic不同) NAT分类 根据Stun协议(RFC3489),NAT大致分为下面四类 1) Full Cone 这种NAT内部的机器A连接过外网机器C后,NAT会打开一个端口.然后外网的任何发到这个打开的端口的UDP数据报都可以到达A.不管是不是C发过来的. 例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88 A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000) 任何发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000) 2) Restricted Cone 这种NAT内部的机器A连接过外网的机器C后,NAT打开一个端口.然后C可以用任何端口和A通信.其他的外网机器不行. 例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88 A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000) 任何从C发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000) 3) Port Restricted Cone 这种NAT内部的机器A连接过外网的机器C后,NAT打开一个端口.然后C可以用原来的端口和A通信.其他的外网机器不行. 例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88 A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000) C(202.88.88.88:2000)发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000) 以上三种NAT通称Cone NAT.我们只能用这种NAT进行UDP打洞. 4) Symmetic
对于这种NAT.连接不同的外部目标.原来NAT打开的端口会变化.而Cone NAT不会.虽然可以用端口猜测.但是成功的概率很小.因此放弃这种NAT的UDP打洞.
第一种情况, 双方都是Symmetric NAPT: 此情况应给不存在什么问题,肯定是不支持UDP穿透。 第二种情况, 双方都是Cone NAPT: 此情况是我们需要的,可以进行UDP穿透。 第三种情况, 一个是Symmetric NAPT, 一个是Cone NAPT: 这个行不行呢,这个问题留给大家吧 |
|