用java实现一个p2p种子搜索功能的方法

介绍

这篇文章给大家分享的是有关用java实现一个p2p种子搜索功能的方法的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。

很多年前对p2p就有很大的兴趣,不过都是停留在理论上,一直没有机会去真正的实践。最近把这个东西实现了一下,从刚开始入手到现在,我觉得有些东西可以分享一下。进入正题吧那就

基本概念

再讲p2p之前,我想先讲一下我们是如何进行下载文件的。我列举一下几种文件下载的方式

1。使用http协议下载,使用的最多的可能就是通过浏览器进行文件的下载。

2。使用ftp下载,ftp有两种模式,一种是港口(主动)模式,这种模式客户端会在本地开启一个端口N(在1023年)建立ftp连接,然后发送给ftp服务器N + 1监听端口用来数据传输,当有防火墙或者客户端被nat的情况下就无法下载。另外一种方式是被动模式(被动),这种模式ftp服务端除了21端口以外会开启一个另外大于1023的端口,也就是说客户端会主动发起ftp连接和数据传输连接,只要ftp服务器开放了这个端口那就不会有问题。

上面两种方式可以统称为cs架构,这种架构下面,资源都集中在服务端,当数据量大到一定程度的时候就会出现问题。为了解决这个问题,我们可能会想到分布式去中心化,于是p2p应运而生,p2p即点对点,这是一种对等架构,每个节点既是客服端又是服务端。

p2p架构

当把资源都存储在每个节点上面的时候,我们可能会想,当我下载一个资源的时候,那我怎么知道这个文件在那些机器上面能下载呢?

早期的p2p架构中存在一个跟踪器的角色,这个追踪负责存储文件的元数据信息。那么现在文件会保存在每个同行上面,然后通过跟踪获取文件信息。

用java实现一个p2p种子搜索功能的方法

这种架构下面我们所有的文件都分布式了,只是追踪会负责存储所有文件的元数据信息,所以追踪只需要存储少量数据,相对于存在文件会相对轻松很多了。

但是一旦出现跟踪服务器挂了或者服务不可用那么就会导致所有的文件都无法下载,因为它还没有完全的分布式,为了完全的去中心化,后面出来一种trackerless架构,

这个时候不在存在追踪这个东西,所有的文件包括文件的元数据信息都分布式存储。

DHT

DHT(分布式哈希表)分布式哈希表,它是用来代替追踪。实现DHT的算法有很多,比如几个概念:

1。nodeid在dht网络中每个nodeid都是160位

2。XOR两个节点之间的距离使用异或来计算

3。溃败表路由表

这里的话还是主要讲实现所以原理这部分的话网上也有很多资料大家可以参考看看

如何实现

实现种子搜索分为两步,第一步是爬的虫,用来爬取网上的种子信息,第二步是加入搜索。

需要具备以下知识:种子,bt dht协议,bencoded

提到p2p不得不提种子,就是那种.torrent结果的那种文件,大家可能都是用过bt种子下载过文件,下载文件使用的是bt协议。那么如何收集网络上面的种子呢?

bt种子包含的主要字段:戳:https://segmentfault.com/a/1190000000681331

在dht中获取的种子叫trackerless洪流,没有宣布这个属性,但是会有节点属性来代替。官方建议不要router.bittorrent.com把这个添加到种子里面,也不要添加到路由表。

1。<强>如何从dht中获取种子

如果想要得到种子信息,那么必须要对dht协议深入了解,bep_0005描述了dht协议

<强>具体可以戳这里http://www.bittorrent.org/beps/bep_0005.html

如何实现一个路由表:

路由表覆盖了所有节点的id,从0到160次的方。路由表可以由桶组成,每个桶覆盖了所有节点的一部分。

刚开始一个路由表只有一个水桶,覆盖了所有的nodeid。每个水桶,只能保持最多K个节点,当前这个K值是8。如果斗已经满了,并且里面的节点都是好的,而且自身的nodeid不在这个桶里面,那么就讲原来的斗分成两个新的桶,分别覆盖0 . . 2 <一口> 159 和<一口> 159 . . 2 <一口> 160

当一个桶已经满了的时候,新节点很容易被丢弃,如果这里面掉的节点线了,那么就会被取代。如果一个节点最近15分钟都没有平过,那么就对这个节点发起平,如果没有返回响应,那么这个节点也会被替代。

每一个桶应该有一个去年改变属性,用来表明这个桶的活跃度。这几种情况会更新这个字段:

用java实现一个p2p种子搜索功能的方法