【精选】udp打洞实现p2p在不同局域网下直接通信

您所在的位置:网站首页 范冰冰的首饰 【精选】udp打洞实现p2p在不同局域网下直接通信

【精选】udp打洞实现p2p在不同局域网下直接通信

2023-11-23 06:00| 来源: 网络整理| 查看: 265

文章目录 前言一、内网穿透的前提1. 了解NAT2.通信双方的NAT类型对穿透的影响 二、实现UDP打洞进行p2p通信1. 首先将双方NAT的IP地址注册到服务器2. 开始udp打洞 总结

前言

p2p 即点对点通信,可以无需经过服务器,依靠内网穿透实现跨局域网通信,在视频通信或文件传输中使用p2p也可以缓解服务器中转压力

一、内网穿透的前提 1. 了解NAT

可以先读下面知道NAT是什么和基本原理 网络地址转换——NAT、NAPT详解

                            NAT的四种类型 1, 全锥型(Full Cone):       将从同一内部IP地址和端口来的所有请求,都映射到相同的外部IP地址和端口。而且,任何外部主机通过向映射的外部地址发送报文,可以实现和内部主机进行通信。这是一种比较宽松的策略,只要建立了内部网络的IP地址和端口与公网IP地址和端口的映射关系,则所有Internet上的主机都可以访问该NAT之后的主机。

2, 受限锥型(Restricted Cone), 也称IP受限锥型:       受限圆锥型NAT也是将从相同的内部IP地址和端口来的所有请求,映射到相同的公网IP地址和端口。但是与完全圆锥型NAT不同,当且仅当内网主机之前己经向公网主机(假设IP地址为P)发送过分组,此公网主机才能够向内网主机发送分组。

3, 端口受限锥型(Port Restricted Cone),也称IP + PORT受限锥型:       类似于受限圆锥型NAT,但更严格。端口受限圆锥型NAT增加了端口号的限制,当且仅当内网主机之前已经向公网主机发送了分组,公网主机才能和此内网主机通信。NAT会将内网地址{X:y}映射成公网地址{A:b}并绑定,如果内网主机之前己经分别与地址为M,端口为n的主机以及地址为P,端口为q的主机通信,所以只有来自这两个公网地址和端口的分组才能到达内网主机。

4, 对称型(Symmetric):       对称型NAT把从同一内网地址和端口到相同目的地址和端口的所有请求,都映射到同一个公网地址和端口。如果同一个内网主机,用相同的内网地址和端口向另一个目的地址发送分组,则会使用不同的映射,而且公网主机只有在接收到分组后,才能向与发送分组的内网主机进行通信。可见,对称性NAT是所有NAT类型中限制最为严格的。

      简单来说,假设主机(192.168.31.18:8888)和服务器(3.3.3.3:80)之间的建立的NAT映射关系为 192.168.31.18:8888 2.2.2.2:1234 3.3.3.3 80 如果用同样的端口和另一服务器(2.2.2.2:80)发起请求, 路由器复用原来的映射关系(192.168.31.18.88882.2.2.2:1234)就为锥型NAT 若再创建新的映射关系则为对称型NAT。

2.通信双方的NAT类型对穿透的影响

      基于UDP的P2P应用需要考虑NAT的类型,因为不同的NAT组合的穿透的方式并不一致,有的能通, 有的不能通。并不是NAT为对称型则无法打通,而是需要看通信双方的NAT类型,双方NAT类型组合为10种,只有对称型与对称型、对称型与端口受限锥型不能穿透,其他都可以,不过一般情况下,锥型NAT穿透比较方便。

二、实现UDP打洞进行p2p通信 1. 首先将双方NAT的IP地址注册到服务器

在这里插入图片描述 实现p2p还是需要服务器中转的,不过这里的中转不是转发信息和,而仅仅是client路由的IP地址。这里的注册ip地址并不需要特殊的操作,只要发一个包给server,server就能获取到发送方的路由的ip和端口并记录下来,然后,当双方需要通信时,将双方的路由的ip地址和端口号转发给对方即可。这样,第一步就完成了。

2. 开始udp打洞

这里以锥形NAT作为例子,当通信双方收到对方路由的ip地址和端口号时,udp打洞就可以开始了,具体操作是相互直接往对方路由的ip和端口发送数据包,注意,要用向服务器注册地址用的端口发送数据包给对方,这样才会复用服务器转发给对方的路由ip和端口。

在这里插入图片描述

第一个数据包和第二数据包其实可以看作同时发送,但是总会有一个先到达对方,第一个会直接被路由器丢弃,因为路由器没有给1.1.1.1这个ip发送过数据,所以这个ip主动发送的数据包会被丢弃。但是client_1发送第一个数据包后路由器(1.1.1.1)会建立一个映射(未完成),当收到对方的syn后,映射建立完成。第二个数据包和第三个数据包同理,client_2的路由器也建立了映射表(如图)。最后,udp打洞成功,实现了p2p通信,没有server转发也能互发数据。

syn和ack只是一个标识而已,这里实现的思路是通路没有打通前,每隔一会发一个syn,收到syn意味着己方已经打通了(只要接收到对方数据包就意味己方路由器已经可以正常收发了),则发送给对方ack,让对方停止发送syn。但自己还是继续发syn,等待对方ack再停止。双方ack后就可以正常点对点通信了。

总结

最后理论结合实践,试着用代码实现一个p2p程序,用两台在不同局域网下的机器,进行跨网通信。具体的实现可以根据不同的思路再加以改进。本人用java写了客户端和服务端用一百来行代码就够了。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3