P2P原理以及如何实现(整理)

前言     

   这几天看了p2p的原理以及实现的demo,整理一下。一共分为三部分,第一是概念原理,第二是demo实现,第三是p2p协议相关以及分类。 

一、概念原理 

比较全面的理解:  https://zhuanlan.zhihu.com/p/30351943

                               http://www.cnblogs.com/pannengzhi/p/4800526.html(推荐)

                              http://www.52im.net/thread-50-1-1.html(推荐)

                              https://cloud.tencent.com/developer/article/1005974(推荐)

以下(通俗理解)转载来自:https://my.oschina.net/gal/blog/141396           

        最近对p2p(peer to peer)技术十分感兴趣,以前用VB的时候曾尝试过学习穿透NAT方面的知识,很可惜那时候并没有成功(由于我当时的兴趣并不大),现在大学开始教 C++,突然间对p2p技术产生兴趣,这有很多方面的原因

        现在基本上很多网络应用的软件都涉及p2p技术(QQ,PPS,对战平台...),p2p技术旨在于摒弃以前只能从服务器获得资源的观念,每台电脑都是一个peer,都可以从其他peer上获取自己想要的资源,而同时自己也在向他人共享自己的资源.这里有一个很大的优势就是可以极大程度节省服务器的带宽.
        打个比喻,优酷和pps,一个是基于服务器->客户端的模式,一个是p2p技术,优酷要想为用户提供高清视频只能通过优化视频压缩(例如最新的H.264)和增大自身服务器带宽.而pps完全不用担心带宽问题,只要用户数量多的话基本上可以满速观看视频. 在这里在停停,pps采用的是rmvb压缩封装,体积比h264flv大上十倍,但是pps依然可以流畅观看.这就是p2p技术的优势.
        当然,我感兴趣的不是p2p在网络视频方面的应用,而是他的穿透NAT的技术,只需要提供一个服务器(当然在p2p下服务端本身可以是客户端)就能令两台或多台处于不同局域网内的电脑通信.另一方面这也算是我学习C++网络编程的入门口.
        在中国大部分用户都使用路由器或交换器之类的其他NAT设备来共享网络,这使得不同内网的用户之间的交流变得十分困难,p2p技术的出现确实另其变得可行和简便.

第二篇:

        首先,在写这第二篇文章时我对现今的p2p技术的成熟度仍不完全了解,基于udp协议的p2p技术可以很确定的说已经完全成熟了,但基于tcp协议的p2p技术是否成熟在我这几天的搜索资料中仍然未能得知.虽然最近得到了一份通过p2p使用tcp协议传输文件的源码,但其真实性仍然未检测,由于有许多可能会影响实验成败的干扰因素(例如NAT设备类型的不同,其结果可能不同),我想我会在接下来的时间主要去验证tcp应用于p2p的可行性.

        可能有很多人问,现在不是有很多软件采用p2p技术传输文件么.这说明tcp用于p2p是可以的.但至少我搜索的资料中很少这方面的消息.我想现在用于文件可靠传输有两个方法(就我知道而言,听说还有raw等其他方法),一个或许就是tcp,这是传输协议上实现的,另一个就是利用udp模仿tcp的确保文件准确完整传输的功能(大概是什么滑动窗口?).

        当然这是我日后的工作,现在我要探讨的是我目前的成果,就是基于udp协议的穿透nat的方法. 

        或许还有人不知道NAT是什么,NAT是英文Network Address Translators的缩写,翻译过来就是网络地址转化器,为什么会出现NAT呢?主要是因为ipv4提供的全球唯一ip已经日渐枯竭,也就是ipv4提供的(x.x.x.x)的地址已经不足以让全球每一台电脑都拥有唯一的ip地址,所以就有NAT的出现(当然,是先出现了NAT才开始慢慢枯竭,因为人们已经预料到ip迟早会用完),NAT可使多台电脑使用同一个全球唯一ip,(当然最近ipv6就要出了).

        而且,类似路由等NAT设备还可以防止内网主机受到外网的攻击,这也就是我们需要穿透NAT的原因,,因为路由只允许内网用户主动连接外网用户,而不允许外网用户主动连接内网用户

        现在按顺序讲下内网于外网连接的步骤(这是理解穿透NAT的阻碍因素的重要部分!!):

        1.内网用户(192.168.1.100)(端口:123)向外网用户(123.123.123.123)(端口:321)发送数据包

        2.数据包经过NAT,NAT将数据包的ip地址改为外网地址(55.55.55.55),并修改端口为另一个数,例如:6000

        3,此时的数据包变成这样: 55.55.55.55: 6000-> 123.123.123.123:321

        4.最后NAT会留下一条记录,表明如下指向 123.123.123.123:123 -> 55.55.55.55:6000 ->192.168.1.100:321

        需注意的是只有留下记录后外网特定方向的数据包(上面第四条的方向)才可以传给内网机器,而且这条记录只能由内网用户先向外网发送第一个数据包才可以产生.最重要的是这条记录只能用于123.123.123.123:123,其他地址发来的数据包NAT是会抛弃掉的! 

        还有一点:就是这条记录具有生命周期,过了一定时间会自动删除!

        了解到这点就可以知道外网和内网的通讯的十分简单的,只要内网用户事先知道服务器的地址,而且先向服务器请求服务就可以建立连接了!

        但是内网与内网的用户该如何实现通讯??? 试想一下,就算你事先知道对方的外网ip,但是你发过去的消息会被对方NAT抛弃掉,好吧,你说可以两个人同时向对方发包,但你画出图来看看会发现也是实现不了的!

         试想一下,如果clientA和clientB都同时向对方的 520端口发送数据包(当然,两边的NAT都会抛弃掉他),虽然两边都会留下记录,但是由于NAT修改了端口号为某个数,这样导致下面两条记录:

        clientA的NAT: 44.44.44.44:520 -> 55.55.55.55:62000 -> 192.168.1.47:520

        clientB的NAT: 55.55.55.55:520 -> 44.44.44.44:75000 -> 192.168.1.5:520

        这两条记录明显不能使clientA和clientB建立起连接,因为双方的NAT都将只接收对方来自520端口的数据包,而对方发送数据包时NAT都会将原始的端口改为62000,75000(这两个数是随机的),这样当然不会建立起连接!

        再回过来想想,如果有一个处在外网的服务器可以同时记录下双方的端口号的话,这样A与B的通讯不是可以建立了么!!!!

二、Demo实现

P2P之UDP穿透(C++)基于windows平台:https://blog.csdn.net/jlccwss/article/details/7180676

P2P之UDP穿透(C++)基于Linux平台:https://github.com/pannzh/P2P-Over-MiddleBoxes-Demo

三、现有p2p协议分类与简介

https://www.cnblogs.com/cgli/archive/2012/05/11/2496027.html

http://www.cnblogs.com/pannengzhi/tag/P2P/

四、应用

BT和磁力链接下载原理

详解什么是BT种子、迅雷下载链接、磁力链接、电骡等及使用教程

--------------------- 本文来自 YehChiTian 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_33850438/article/details/79700133?utm_source=copy

猜你喜欢

转载自blog.csdn.net/huangyimo/article/details/82887160
P2P