magent java_bt种子简介与magnet磁力介绍

BT下载相信老司机们都接触过,绝大部分网友也曾经热血贲张地在网络上狂呼“求种”。不过有一个现象大家不知道注意过没,这两年尽管大家叫的仍是“求种”“发图不发种,XX被人捅”,但求到的资源,却往往不是BT种子了,而且一串串的神秘代码,也就是BT磁力链Magnet链接。

b65413fa911abeba55cf31223f5c57ac.gif

为什么BT种子会慢慢被磁链取而代之?它们都可以用于BT下载,除了文件和字符串这表面上的区别,背后的技术上又有何不同?

BT种子有何局限?

BT下载大家都用得多,不过其背后原理,或许也只是有所耳闻。我们都知道BT下载基于P2P技术,数据在用户之间传输,越多用户参与到下载和上传,下载的速度也会更快。

不过,一群人就算是躺着滚地板,也有很多阵仗可选,更别说是一群人在干相互传输数据这般复杂的事情了。即使同是P2P,不同技术之间区别也很大。BT种子和BT磁链,其背后的技术细节,也有着显著差异。

82f52bb7e907278655e505df80fef5f4.gif

先来说说BT种子。当我们拿到一个BT种子,首先意味着我们拿到了BT资源的文件信息——就如同怎样的种子就会种出怎样的树,文件信息决定了你会下载到苍老师还是葫芦娃。

同时,BT种子还包含了Tracker信息,用以告诉你BT下载需要走哪个Tracker,也就是服务器开始——没错,利用BT种子来进行下载,还是得先走服务器这个流程。用BT种子下载,需要服务器先告诉你其他用户的IP,才能开始数据传输。在这种情况下玩BT,尽管也是P2P下载,但仍然离不开服务器。

这就造成了一个问题,一旦某个BT服务器翘辫子,那么使用该服务器作为Tracker的BT种子,就会失效。而BT服务器挂掉的情况,不要太多。这里既存在服务器自个儿关停的情况,也存在服务器被查水表的情况。

不少老司机应该还对2009年著名BT下载站“BTChina”被查水表心有余悸。随BTChina倒下的不仅仅有一票BT资源站,还有无数的Tracker服务器,这直接导致很多BT种子成为了死种。

直到现在,有经验的老司机在找旧资源的时候,如果看到资源是BT种子,很有可能会直接放弃——除非迅雷等之类的离线下载服务器有缓存相应资源,不然这种子基本就是摆设;而离线下载的和谐力度,大家都懂的。死种、离线和谐都见证了下载中央服务器的脆弱,人们急需续命能力更强的下载方式。历史的进程,就悄然走到了磁力链接的身旁。

磁力链接有啥好?

显然,BT种子的死穴在于Tracker服务器。其实BT下载资源本身就不由服务器提供,服务器提供的只是P2P参与者的信息。那么能不能跳过Tracker这一步,直接连接其他用户进行P2P?BT磁力链接就可以做到这一点。

一般人看到磁力链接,看到的是不明所以的神秘代码,但这神秘代码,其实可以包含很多信息。磁链包含了文件信息,这自然不必说。磁链的文件信息的组合很灵活,不过必须的就一个Hash码。除此以外,磁链还可以包含Tracker地址、DHT节点等信息,但无论如何,必须的仍就只有一个Hash码。

附:磁链可包含的一些参数,必须的只有“xt”

dn(显示名称)- 文件名

xl(绝对长度)- 文件字节数

xt(eXact Topic)- 包含文件散列函数值的URN

as(可接受来源) - 在线文件的网络链接

xs(绝对资源)- P2P链接

kt(关键字)- 用于搜索的关键字

mt(文件列表)- 链接到一个包含磁力链接的元文件 (MAGMA - MAGnet MAnifest)

tr(Tracker地址)- BT下载的Tracker URL

磁力链接可以让用户直接通过DHT网络进行P2P下载,无需经由Tracker服务器。所谓的DHT网络,全称是“Distributed Hash Table”,也就是分布式储存、只用文件Hash码来辨别资源的的网络。这个网络中,用户作为节点存在,每个用户都可以作为P2P的发起点和传播点,利用磁链进行BT下载,不需要找Tracker服务器,只需要连上DHT网络的节点,就可以开始了。

当然,就算使用磁链进行BT下载,如果磁链提供了Tracker信息,Tracker服务器也能大大提高下载效率,这是肯定的。一些下载软件下载磁链的时候,会把自带的一些Tracker信息结合磁链封装成BT种子,加快下载效率。

但总的来说,磁链可谓是一脚踢开了服务器!你在网上看到一串Hash码,直接在前面加上“ magnet:?xt=urn:btih: ”,就能生成一个可用的磁链,下载到Hash码对应的文件了。显然,磁链对比BT种子,优势是显而易见的,这体现在以下方面。

传播方便。作为一串文字,磁链显然比BT种子更容易传播,粘贴一段文字可比上传一个文件省时省力多了。

便于储存整理。如果你拥有很多很多磁力链,你可以把它们都放到一个文档或者表格中,整理得井井有条。很多资源站放种子合集,也可以轻易贴出满满一网页的磁链。而BT种子作为文件,就没有这么方便了。在储存空间上,磁链更是具有得天独厚的优势,海盗湾把所有的种子转换成磁链后,体积只有90M,任何一台电脑都可以完全装下海盗湾的BT资源。

27b16449e6c734a56a984c01dc30b07c.gif

易于生成。当你看到网友有某个好资源,只要问对面生成一下该文件的Hash码,就能够制作一个磁链了,不需要辛辛苦苦把BT种子给翻出来。

资源存活力强。磁链不需要Tracker服务器,直连DHT网络。只要仍有用户在做种,资源就仍然存活。和BT种子相比,磁力链接的优点非常突出。所以现在求种直接甩你磁力链接/Hash码,也就理所当然了。

可见,相比BT种子,磁链更容易发挥出BT下载的P2P精神。得益于磁链,2009年后一度式微的BT下载又重获生机。面对日渐和谐的离线下载,BT磁链仍大有用武之地,希望大家都能从磁链中享用到BT下载的乐趣!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java通过magnet连接下载torrent文件需要用到第三方库,比如BT种子下载器Transmission的Java API。 以下是一个简单的示例代码: ```java import java.net.URL; import java.util.concurrent.TimeUnit; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.util.EntityUtils; import org.json.JSONObject; import org.json.JSONTokener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import com.github.axet.wget.WGet; import com.github.axet.wget.info.URLInfo; import com.github.axet.wget.info.ex.DownloadError; import com.github.axet.wget.info.ex.DownloadInterruptedError; import com.github.axet.wget.info.ex.DownloadMultipartError; import com.github.axet.wget.info.ex.DownloadRetry; import com.github.axet.wget.info.ex.DownloadSSLException; import com.github.axet.wget.info.ex.DownloadTimeoutException; import com.github.axet.wget.info.ex.DownloadVerificationException; @RestController public class TorrentDownloadController { private static final Logger LOGGER = LoggerFactory.getLogger(TorrentDownloadController.class); private static final String TRANSMISSION_API_VERSION = "v2.94"; private static final String TRANSMISSION_RPC_URI = "/transmission/rpc"; private static final String TRANSMISSION_RPC_URL = "http://localhost:9091" + TRANSMISSION_RPC_URI; private static final String MAGNET_URI_PREFIX = "magnet:?xt=urn:btih:"; private static final int CONNECT_TIMEOUT = 10000; private static final int SOCKET_TIMEOUT = 30000; private static final PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); static { connectionManager.setMaxTotal(100); connectionManager.setDefaultMaxPerRoute(20); } @GetMapping(value = "/download/{magnetUri}", produces = MediaType.APPLICATION_JSON_VALUE) public JSONObject download(@PathVariable String magnetUri) throws Exception { LOGGER.info("Downloading torrent from magnet URI: {}", magnetUri); String torrentUrl = getTorrentUrlFromMagnetUri(magnetUri); LOGGER.info("Torrent URL: {}", torrentUrl); // Download torrent file String torrentFilePath = downloadTorrentFile(torrentUrl); LOGGER.info("Torrent file downloaded to: {}", torrentFilePath); // Add torrent to Transmission JSONObject addTorrentResponse = addTorrentToTransmission(torrentFilePath); LOGGER.info("Add torrent response: {}", addTorrentResponse); return addTorrentResponse; } private String getTorrentUrlFromMagnetUri(String magnetUri) throws Exception { if (!magnetUri.startsWith(MAGNET_URI_PREFIX)) { throw new IllegalArgumentException("Invalid magnet URI: " + magnetUri); } String hash = magnetUri.substring(MAGNET_URI_PREFIX.length()); String infoHash = hash.split("&")[0]; String infoUrl = "https://itorrents.org/torrent/" + infoHash + ".torrent"; HttpClient httpClient = HttpClientBuilder.create() .setConnectionManager(connectionManager) .setConnectionManagerShared(true) .build(); HttpGet httpGet = new HttpGet(infoUrl); httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"); HttpResponse response = httpClient.execute(httpGet); if (response.getStatusLine().getStatusCode() != 200) { throw new RuntimeException("Failed to get torrent file URL, HTTP error code: " + response.getStatusLine().getStatusCode()); } String responseBody = EntityUtils.toString(response.getEntity()); JSONObject jsonResponse = new JSONObject(new JSONTokener(responseBody)); String torrentUrl = jsonResponse.getString("url"); return torrentUrl; } private String downloadTorrentFile(String torrentUrl) throws Exception { URL url = new URL(torrentUrl); URLInfo urlInfo = new URLInfo(url); String fileName = urlInfo.getFile().substring(urlInfo.getFile().lastIndexOf('/') + 1); WGet wGet = new WGet(url, fileName); wGet.setConnectTimeout(CONNECT_TIMEOUT); wGet.setReadTimeout(SOCKET_TIMEOUT); try { wGet.download(); } catch (DownloadRetry e) { LOGGER.error("Failed to download torrent file: {}", e.getMessage()); throw new RuntimeException(e); } catch (DownloadTimeoutException e) { LOGGER.error("Failed to download torrent file: {}", e.getMessage()); throw new RuntimeException(e); } catch (DownloadMultipartError e) { LOGGER.error("Failed to download torrent file: {}", e.getMessage()); throw new RuntimeException(e); } catch (DownloadInterruptedError e) { LOGGER.error("Failed to download torrent file: {}", e.getMessage()); throw new RuntimeException(e); } catch (DownloadVerificationException e) { LOGGER.error("Failed to download torrent file: {}", e.getMessage()); throw new RuntimeException(e); } catch (DownloadSSLException e) { LOGGER.error("Failed to download torrent file: {}", e.getMessage()); throw new RuntimeException(e); } catch (DownloadError e) { LOGGER.error("Failed to download torrent file: {}", e.getMessage()); throw new RuntimeException(e); } return fileName; } private JSONObject addTorrentToTransmission(String torrentFilePath) throws Exception { String addTorrentUrl = TRANSMISSION_RPC_URL + "/" + TRANSMISSION_API_VERSION + "/torrent-add"; HttpClient httpClient = HttpClientBuilder.create() .setConnectionManager(connectionManager) .setConnectionManagerShared(true) .build(); HttpGet httpGet = new HttpGet(addTorrentUrl); httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"); String jsonRequest = "{\"method\":\"torrent-add\",\"arguments\":{\"paused\":false,\"download-dir\":\"/downloads\",\"filename\":\"" + torrentFilePath + "\"}}"; httpGet.setHeader("Content-Type", "application/json"); httpGet.setHeader("X-Transmission-Session-Id", "null"); httpGet.setEntity(IOUtils.toInputStream(jsonRequest)); HttpResponse response = httpClient.execute(httpGet); if (response.getStatusLine().getStatusCode() == 409) { String sessionHeader = response.getFirstHeader("X-Transmission-Session-Id").getValue(); httpGet.setHeader("X-Transmission-Session-Id", sessionHeader); httpGet.setEntity(IOUtils.toInputStream(jsonRequest)); response = httpClient.execute(httpGet); } String responseBody = EntityUtils.toString(response.getEntity()); JSONObject jsonResponse = new JSONObject(new JSONTokener(responseBody)); return jsonResponse; } } ``` 这个示例代码使用了Transmission的Java API来添加torrent文件到Transmission,如果你想使用其他BT下载工具或者其他BT下载库,你需要修改相应的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值