這篇文章給大家分享的是有關(guān)用java實現(xiàn)一個p2p種子搜索功能的方法的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。
很多年前對p2p就有很大的興趣,不過都是停留在理論上,一直沒有機會去真正的實踐。最近把這個東西實現(xiàn)了一下,從剛開始入手到現(xiàn)在,我覺得有些東西可以分享一下。進(jìn)入正題吧那就
基本概念再講p2p之前,我想先講一下我們是如何進(jìn)行下載文件的。我列舉一下幾種文件下載的方式
1.使用http協(xié)議下載,使用的最多的可能就是通過瀏覽器進(jìn)行文件的下載。
2.使用ftp下載,ftp有兩種模式,一種是port(主動)模式,這種模式客戶端會在本地開啟一個端口N(>1023)建立ftp連接,然后發(fā)送給ftp服務(wù)器N+1監(jiān)聽端口用來數(shù)據(jù)傳輸,當(dāng)有防火墻或者客戶端被nat的情況下就無法下載。另外一種方式是被動模式(passive),這種模式ftp服務(wù)端除了21端口以外會開啟一個另外大于1023的端口,也就是說客戶端會主動發(fā)起ftp連接和數(shù)據(jù)傳輸連接,只要ftp服務(wù)器開放了這個端口那就不會有問題。
上面兩種方式可以統(tǒng)稱為cs架構(gòu),這種架構(gòu)下面,資源都集中在服務(wù)端,當(dāng)數(shù)據(jù)量大到一定程度的時候就會出現(xiàn)問題。為了解決這個問題,我們可能會想到分布式去中心化,于是p2p應(yīng)運而生,p2p即 peer to peer,這是一種對等架構(gòu),每個節(jié)點既是客服端又是服務(wù)端。
p2p架構(gòu)當(dāng)把資源都存儲在每個節(jié)點上面的時候,我們可能會想,當(dāng)我下載一個資源的時候 ,那我怎么知道這個文件在那些機器上面能下載呢?
早期的p2p架構(gòu)中存在一個tracker的角色,這個tracker負(fù)責(zé)存儲文件的元數(shù)據(jù)信息。那么現(xiàn)在文件會保存在每個peer上面,然后通過tracker獲取文件信息。
這種架構(gòu)下面我們所有的文件都分布式了,只是tracker會負(fù)責(zé)存儲所有文件的元數(shù)據(jù)信息,所以tracker只需要存儲少量數(shù)據(jù),相對于存在文件會相對輕松很多了。
但是一旦出現(xiàn)tracker服務(wù)器掛了或者服務(wù)不可用那么就會導(dǎo)致所有的文件都無法下載,因為它還沒有完全的分布式,為了完全的去中心化,后面出來一種trackerless架構(gòu),
這個時候不在存在tracker這個東西,所有的文件包括文件的元數(shù)據(jù)信息都分布式存儲。
DHTDHT(Distributed Hash Table)分布式哈希表,它是用來代替tracker。實現(xiàn)dht的算法有很多,比如Kademlia算法等等。
幾個概念:
1.nodeid 在dht網(wǎng)絡(luò)中每個nodeid都是160bit
2.XOR 兩個節(jié)點之間的距離使用異或來計算
3.routting table路由表
這里的話還是主要講實現(xiàn)所以原理這部分的話 網(wǎng)上也有很多資料 大家可以參考看看
如何實現(xiàn)實現(xiàn)種子搜索分為兩步,第一步是爬蟲,用來爬取網(wǎng)上的種子信息,第二步是加入搜索。
需要具備以下知識:種子,bittorrent dht 協(xié)議,bencoded
提到p2p不得不提種子,就是那種.torrent結(jié)果的那種文件,大家可能都是用過bt種子下載過文件,下載文件使用的是bittorrent協(xié)議。那么如何收集網(wǎng)絡(luò)上面的種子呢?
bt種子包含的主要字段:戳:https://segmentfault.com/a/1190000000681331
在dht中獲取的種子叫trackerless torrent,沒有announce這個屬性,但是會有nodes屬性來代替。官方建議不要router.bittorrent.com把這個添加到種子里面,也不要添加到路由表。
1.如何從dht中獲取種子如果想要得到種子信息,那么必須要對DHT Protocol深入了解,bep_0005描述了DHT Protocol
具體可以戳這里 http://www.bittorrent.org/beps/bep_0005.html
如何實現(xiàn)一個路由表:
路由表覆蓋了所有Node的id,從0到2的160次方。路由表可以由bucket組成,每個bucket覆蓋了所有node的一部分。
剛開始一個路由表只有一個bucket,覆蓋了所有的nodeid。每個bucket,只能hold最多K個nodes,當(dāng)前這個K值是8。如果bucket已經(jīng)滿了,并且里面的node都是好的,而且自身的nodeid不在這個bucket里面,那么就講原來的bucket分成兩個新的bucket,分別覆蓋0..2159和2159..2160。
當(dāng)一個bucket已經(jīng)滿了的時候,新node很容易被丟棄,如果這里面的node掉線了,那么就會被replace。如果一個節(jié)點最近15分鐘都沒有ping過,那么就對這個節(jié)點發(fā)起ping,如果沒有返回response,那么這個節(jié)點也會被replace。
每一個bucket應(yīng)該有一個last changed屬性,用來表明這個bucket的活躍度。這幾種情況會更新這個字段:
1.bucket里面的node被ping了并且有response
2.一個node添加到了這個bucket里面
3.bucket里面的node被replace了
bucket在15分鐘之內(nèi)沒有更新這個字段的話 ,那么就會隨機選取一個在該bucket范圍內(nèi)的id,做find_node操作。
KRPC Protocoldht網(wǎng)絡(luò)中通過KRPC Protocol來傳遞消息。
1.ping
ping查詢主要用來心跳檢查
2.find_node
查找一個節(jié)點,對方會從自己的路由表中查詢最近的N個節(jié)點返回,一般是8個
3.get_peers
根據(jù)infohash查找擁有該infohash的peer,如果查到到返回peers,沒有查找到返回nodes
4.announce_peer
告訴其他的peers,自己也擁有infohash。
注意以上四個都會刷新路由表
一開始路由表里面沒有任何節(jié)點,所以需要從超級節(jié)點(例如dht.transmissionbt.com
等等)通過find_node請求來查找并添加節(jié)點,返回的節(jié)點在進(jìn)行find_node。
我自己實現(xiàn)的路由表稍微和上面描述的不太一樣。
dht網(wǎng)絡(luò)中采用udp進(jìn)行數(shù)據(jù)傳輸,所以我只用開啟一個upd端口不斷的發(fā)送find_node請求建立路由表,然后通過get_peers和announce_peer來獲取種子的infohash。
當(dāng)我們加入dht網(wǎng)絡(luò)后,通過上面介紹的四個方法只能得到種子文件的infohash,所以我們還需要通過infohash來下載種子,具體可以參照bep_009http://www.bittorrent.org/beps/bep_0009.html
我們主要通過bep_009來獲取種子的名字字段,獲取了文件名字段就可以根據(jù)名字和infohash來建立索引提供搜索。(這里主要構(gòu)建磁力鏈接,有了磁力鏈接就可以去迅雷,百度網(wǎng)盤等去下載資源啦)
大部分磁力鏈接格式:magnet:?xt=urn:btih:infohash
感謝各位的閱讀!關(guān)于用java實現(xiàn)一個p2p種子搜索功能的方法就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
網(wǎng)站欄目:用java實現(xiàn)一個p2p種子搜索功能的方法-創(chuàng)新互聯(lián)
本文鏈接:http://www.rwnh.cn/article8/gcdop.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)、網(wǎng)站設(shè)計、標(biāo)簽優(yōu)化、全網(wǎng)營銷推廣、服務(wù)器托管、做網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容