溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

用java實(shí)現(xiàn)一個(gè)p2p種子搜索功能的方法

發(fā)布時(shí)間:2020-08-24 12:03:04 來(lái)源:億速云 閱讀:692 作者:小新 欄目:編程語(yǔ)言

這篇文章給大家分享的是有關(guān)用java實(shí)現(xiàn)一個(gè)p2p種子搜索功能的方法的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。

很多年前對(duì)p2p就有很大的興趣,不過(guò)都是停留在理論上,一直沒(méi)有機(jī)會(huì)去真正的實(shí)踐。最近把這個(gè)東西實(shí)現(xiàn)了一下,從剛開(kāi)始入手到現(xiàn)在,我覺(jué)得有些東西可以分享一下。進(jìn)入正題吧那就

基本概念

再講p2p之前,我想先講一下我們是如何進(jìn)行下載文件的。我列舉一下幾種文件下載的方式

1.使用http協(xié)議下載,使用的最多的可能就是通過(guò)瀏覽器進(jìn)行文件的下載。

2.使用ftp下載,ftp有兩種模式,一種是port(主動(dòng))模式,這種模式客戶端會(huì)在本地開(kāi)啟一個(gè)端口N(>1023)建立ftp連接,然后發(fā)送給ftp服務(wù)器N+1監(jiān)聽(tīng)端口用來(lái)數(shù)據(jù)傳輸,當(dāng)有防火墻或者客戶端被nat的情況下就無(wú)法下載。另外一種方式是被動(dòng)模式(passive),這種模式ftp服務(wù)端除了21端口以外會(huì)開(kāi)啟一個(gè)另外大于1023的端口,也就是說(shuō)客戶端會(huì)主動(dòng)發(fā)起ftp連接和數(shù)據(jù)傳輸連接,只要ftp服務(wù)器開(kāi)放了這個(gè)端口那就不會(huì)有問(wèn)題。

上面兩種方式可以統(tǒng)稱為cs架構(gòu),這種架構(gòu)下面,資源都集中在服務(wù)端,當(dāng)數(shù)據(jù)量大到一定程度的時(shí)候就會(huì)出現(xiàn)問(wèn)題。為了解決這個(gè)問(wèn)題,我們可能會(huì)想到分布式去中心化,于是p2p應(yīng)運(yùn)而生,p2p即 peer to peer,這是一種對(duì)等架構(gòu),每個(gè)節(jié)點(diǎn)既是客服端又是服務(wù)端。

p2p架構(gòu)

當(dāng)把資源都存儲(chǔ)在每個(gè)節(jié)點(diǎn)上面的時(shí)候,我們可能會(huì)想,當(dāng)我下載一個(gè)資源的時(shí)候 ,那我怎么知道這個(gè)文件在那些機(jī)器上面能下載呢?

早期的p2p架構(gòu)中存在一個(gè)tracker的角色,這個(gè)tracker負(fù)責(zé)存儲(chǔ)文件的元數(shù)據(jù)信息。那么現(xiàn)在文件會(huì)保存在每個(gè)peer上面,然后通過(guò)tracker獲取文件信息。

用java實(shí)現(xiàn)一個(gè)p2p種子搜索功能的方法

這種架構(gòu)下面我們所有的文件都分布式了,只是tracker會(huì)負(fù)責(zé)存儲(chǔ)所有文件的元數(shù)據(jù)信息,所以tracker只需要存儲(chǔ)少量數(shù)據(jù),相對(duì)于存在文件會(huì)相對(duì)輕松很多了。

但是一旦出現(xiàn)tracker服務(wù)器掛了或者服務(wù)不可用那么就會(huì)導(dǎo)致所有的文件都無(wú)法下載,因?yàn)樗€沒(méi)有完全的分布式,為了完全的去中心化,后面出來(lái)一種trackerless架構(gòu),

這個(gè)時(shí)候不在存在tracker這個(gè)東西,所有的文件包括文件的元數(shù)據(jù)信息都分布式存儲(chǔ)。

DHT

DHT(Distributed Hash Table)分布式哈希表,它是用來(lái)代替tracker。實(shí)現(xiàn)dht的算法有很多,比如Kademlia算法等等。
幾個(gè)概念:

1.nodeid 在dht網(wǎng)絡(luò)中每個(gè)nodeid都是160bit

2.XOR 兩個(gè)節(jié)點(diǎn)之間的距離使用異或來(lái)計(jì)算

3.routting table路由表

這里的話還是主要講實(shí)現(xiàn)所以原理這部分的話 網(wǎng)上也有很多資料 大家可以參考看看

如何實(shí)現(xiàn)

實(shí)現(xiàn)種子搜索分為兩步,第一步是爬蟲(chóng),用來(lái)爬取網(wǎng)上的種子信息,第二步是加入搜索。

需要具備以下知識(shí):種子,bittorrent dht 協(xié)議,bencoded

提到p2p不得不提種子,就是那種.torrent結(jié)果的那種文件,大家可能都是用過(guò)bt種子下載過(guò)文件,下載文件使用的是bittorrent協(xié)議。那么如何收集網(wǎng)絡(luò)上面的種子呢?

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

在dht中獲取的種子叫trackerless torrent,沒(méi)有announce這個(gè)屬性,但是會(huì)有nodes屬性來(lái)代替。官方建議不要router.bittorrent.com把這個(gè)添加到種子里面,也不要添加到路由表。

1.如何從dht中獲取種子

如果想要得到種子信息,那么必須要對(duì)DHT Protocol深入了解,bep_0005描述了DHT Protocol

具體可以戳這里 http://www.bittorrent.org/beps/bep_0005.html

如何實(shí)現(xiàn)一個(gè)路由表:

路由表覆蓋了所有Node的id,從0到2的160次方。路由表可以由bucket組成,每個(gè)bucket覆蓋了所有node的一部分。

剛開(kāi)始一個(gè)路由表只有一個(gè)bucket,覆蓋了所有的nodeid。每個(gè)bucket,只能hold最多K個(gè)nodes,當(dāng)前這個(gè)K值是8。如果bucket已經(jīng)滿了,并且里面的node都是好的,而且自身的nodeid不在這個(gè)bucket里面,那么就講原來(lái)的bucket分成兩個(gè)新的bucket,分別覆蓋0..2159和2159..2160。

當(dāng)一個(gè)bucket已經(jīng)滿了的時(shí)候,新node很容易被丟棄,如果這里面的node掉線了,那么就會(huì)被replace。如果一個(gè)節(jié)點(diǎn)最近15分鐘都沒(méi)有ping過(guò),那么就對(duì)這個(gè)節(jié)點(diǎn)發(fā)起ping,如果沒(méi)有返回response,那么這個(gè)節(jié)點(diǎn)也會(huì)被replace。

每一個(gè)bucket應(yīng)該有一個(gè)last changed屬性,用來(lái)表明這個(gè)bucket的活躍度。這幾種情況會(huì)更新這個(gè)字段:

1.bucket里面的node被ping了并且有response

2.一個(gè)node添加到了這個(gè)bucket里面

3.bucket里面的node被replace了

bucket在15分鐘之內(nèi)沒(méi)有更新這個(gè)字段的話 ,那么就會(huì)隨機(jī)選取一個(gè)在該bucket范圍內(nèi)的id,做find_node操作。

KRPC Protocol

dht網(wǎng)絡(luò)中通過(guò)KRPC Protocol來(lái)傳遞消息。

1.ping

ping查詢主要用來(lái)心跳檢查

2.find_node

查找一個(gè)節(jié)點(diǎn),對(duì)方會(huì)從自己的路由表中查詢最近的N個(gè)節(jié)點(diǎn)返回,一般是8個(gè)

3.get_peers

根據(jù)infohash查找擁有該infohash的peer,如果查到到返回peers,沒(méi)有查找到返回nodes

4.announce_peer

告訴其他的peers,自己也擁有infohash。

注意以上四個(gè)都會(huì)刷新路由表

一開(kāi)始路由表里面沒(méi)有任何節(jié)點(diǎn),所以需要從超級(jí)節(jié)點(diǎn)(例如dht.transmissionbt.com等等)通過(guò)find_node請(qǐng)求來(lái)查找并添加節(jié)點(diǎn),返回的節(jié)點(diǎn)在進(jìn)行find_node。

我自己實(shí)現(xiàn)的路由表稍微和上面描述的不太一樣。

dht網(wǎng)絡(luò)中采用udp進(jìn)行數(shù)據(jù)傳輸,所以我只用開(kāi)啟一個(gè)upd端口不斷的發(fā)送find_node請(qǐng)求建立路由表,然后通過(guò)get_peers和announce_peer來(lái)獲取種子的infohash。

當(dāng)我們加入dht網(wǎng)絡(luò)后,通過(guò)上面介紹的四個(gè)方法只能得到種子文件的infohash,所以我們還需要通過(guò)infohash來(lái)下載種子,具體可以參照bep_009http://www.bittorrent.org/beps/bep_0009.html

我們主要通過(guò)bep_009來(lái)獲取種子的名字字段,獲取了文件名字段就可以根據(jù)名字和infohash來(lái)建立索引提供搜索。(這里主要構(gòu)建磁力鏈接,有了磁力鏈接就可以去迅雷,百度網(wǎng)盤(pán)等去下載資源啦

大部分磁力鏈接格式:magnet:?xt=urn:btih:infohash

感謝各位的閱讀!關(guān)于用java實(shí)現(xiàn)一個(gè)p2p種子搜索功能的方法就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI