ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P2P打洞过程详解

2022-01-29 22:02:32  阅读:347  来源: 互联网

标签:打洞 ip 端口 server 详解 P2P NAT PS1 port


  • 什么是NAT。

NAT(Network Address Translation),网络地址转换协议。NAT是1994年提出的,当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但现在又想和因特网上的主机通信时,就可以使用NAT技术。

比如说内网ip地址192.168.1.155与外网ip地址150.158.106.96是无法直接通信,如果想要让这两个ip能够直接通信,就需要用到NAT技术将ip地址192.168.1.155先转换成公网ip地址和端口之后就可以进行通信了。

NAT的出现主要是因为IP4地址耗尽,理论上当全球IP6全面普及使用之后,NAT是可以退出历史舞台的。可见NAT的本质就是让一群机器公用同一个IP,这样就暂时解决了IP短缺的问题。

NAT的出现还有一个出于网络安全的原因,外网的主机要想攻击内网的主机,必须要经过防火墙,经过NAT转换才能找到内网的主机。

  • 路由器种类
  1. 基本型(没用)

当一个内网设备要访问外网时,路由器为这个内网ip分配一个外网ip完全供这个设备使用,通常需要路由器有多个外网ip。

  1. 对称型(无法穿透)

当一个内网设备要访问外网时,根据源地址,源端口,目的地址,目的端口的不同映射成外网ip下不同的端口进行会话。所以只要(源地址,源端口,目的地址,目的端口)其中的一个不同,会话的端口就会改变,所以无法穿透。

  1. 完全克隆型(最容易穿透)

当一个内网设备要访问外网时,根据源地址,源端口的不同映射成外网ip下不同的端口进行会话。

  1. 端口限制克隆型(可以穿透)

当一个内网设备要访问外网时,根据源地址,源端口的不同映射成外网ip下不同的端口进行会话。但路由器只接受目的端口返回的udp数据。

  1. 端口地址限制克隆型(可以穿透)

当一个内网设备要访问外网时,根据源地址,源端口的不同映射成外网ip下不同的端口进行会话。但路由器只接受目的端口且目的ip返回的udp数据。

以上3,4,5类路由器只要源地址和源端口相同,无论访问外网哪一个地址,映射成的端口都相同,这是这3种类型能穿墙的原因。

  • 如何判断是哪一种网络。

通过使用STUN服务器检测设备所处网络的NAT类型,STUN服务器需要两个公网IP。

我们假定client是要检测的设备,server是STUN服务器,并假设server的两公网SOCKET的IP地址和端口号分别是IP1:port和IP2:port。

步骤1:

client向server IP1:port发送请求,server使用IP1:port将收到请求的源IP和port(即设备的公网IP地址和端口号)回复给client,如果得到的公网IP和设备自身的IP一样,则判定设备自身处在公网,无NAT,检测结束,否则进行下一步。

步骤2:

client向server IP1:port发送请求,server使用IP2:port来回复,如果设备能收到回复,则判定client的NAT为完全锥形(Full Cone NAT),检测结束,否则进行下一步。

步骤3:

client向server IP2:port发送请求,server使用IP2:port将收到的源IP和port回复给client,client判断此port和步骤1得到的port是否一样,如果不一样,则为对称型(Symmetric NAT),检测结束;

如果一样,则为限制型(Restricted Cone NAT),这时候需要进一步检查是地址限制型NAT还是端口限制型NAT。

步骤4:

client向server IP2:port发送请求,要求server使用该IP的另一个端口来回复,server使用IP2:port2回复请求,如果client能收到回复,则判断为地址限制型(Address Restricted Cone) NAT,否则为端口限制型(Port Restricted Cone) NAT

  • udp打洞过程
  1. 网络拓扑图

外S1,外S2为假设在外部的两个辅助穿墙的server

PC1为子网1下想要连接PS1的client

PS1,为子网2下的,提供数据的server

  1. 打洞流程
  1. PS1 用udp向 外S1,S2 发送 注册登记请求,请求登记成功之后,外S1,S2

持有了PS1用于注册的名称(假设为“manager”)、外部的IP、外部的port、以及server

分配给PS1的session(由于udp不是长链接,所以,需要一个session区分对端是否断线重连)。由S1,S2持续向PS1发送心跳保活。

  1. 接着PC1 在 外S1上注册登记(假设为”client”)
  2. PC1创建两个子socket,一个用于send,一个用于recv,在S1上登记两个子sock,此时,

S1上有PC1 的三个外网ip+port,一个用于通讯,另外两个用于和PS1打洞

  1. PC1 请求 S1向 manager 发送 连接请求 (附带了client的session,client的两个sock外网ip+port)

  1. PS1 收到 S1 来的连接请求之后,创建两个sock,一个用于发送,一个用于接收,并通过S1发给PC1,并向PC1,的两个端口发送心跳包(第一次打洞,由于PC1从来没有给PS1发过数据,这些心跳包可能PC1收不到),

  1. PC1收到S1传来的PS1的两个端口之后,也向PS1发送心跳(第二次打洞,如果打洞成功,此时PS1应该能收到数据)

  1. PS1 检测到 PC1有发过来的数据,回两个心跳,并callback给其他逻辑(server端建立完成)
  2. PC1只要收到了PS1发过来的任何数据,直接返回connect连接成功,如果超时,则打洞失败,
  3. PC1 注销在S1的登记

PS:整个逻辑下来,PS1 和 PC1的socket中可能残存有未处理的心跳包(用于打洞用的数据)p

标签:打洞,ip,端口,server,详解,P2P,NAT,PS1,port
来源: https://blog.csdn.net/faststream/article/details/122748208

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有