1 个不稳定版本

0.1.0 2020 年 12 月 22 日

#2027网络编程

MIT/Apache

390KB
6.5K SLoC

cratetorrent

Cratetorrent 是一个实现 BitTorrent 版本 1 协议的 Rust 包。

Cargo Documentation License


它可以作为一个库使用,同时也提供了一个简单的 CLI 归档应用程序。它基于 tokio,并使用异步 IO 以获得高性能。

该名称是对 C++ 的 libtorrent 库的致敬,我在 C++ 中第一次编写我的归档引擎时,从中学到了很多经验。

功能

  • 多归档下载或上传,具有任意数量的对等连接。
  • 手动指定要下载的种子。
  • 从 HTTP 跟踪器获取对等连接。
  • 每个归档的基本可配置性。
  • 良好的性能

    在我的相当慢的互联网连接上,峰值下载速率约为 9 MBps,Ubuntu 20.04 LTS (~2.8 GB) 在约 5 分钟内以 8-9 MBps 的下载速率下载,即几乎充分利用了链路。

功能持续增加,请参阅 项目里程碑

最终,我希望将 cratetorrent 开发成一个功能齐全的 BitTorrent 引擎库,可以用于作为 torrent 客户端的底层引擎。这意味着 cratetorrent 将在未来支持流行客户端支持的功能(如 DHT、磁力链接、BitTorrent 协议 2、流加密等)。

下载示例

use cratetorrent::prelude::*;
                                                                             
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // spawn the engine with a default config
    let conf = Conf::new("/tmp/downloads");
    let (engine, mut alert_rx) = engine::spawn(conf)?;
                                                                             
    // parse torrent metainfo and start the download
    let metainfo = tokio::fs::read("/tmp/imaginary.torrent").await?;
    let metainfo = Metainfo::from_bytes(&metainfo)?;
    let torrent_id = engine.create_torrent(TorrentParams {
        metainfo,
        // tell the engine to assign a randomly chosen free port
        listen_addr: None,
        // here we could specify peers we knew of that we'd want
        // to connect to
        mode: Mode::Download { seeds: Vec::new() },
        conf: None,
    })?;
                                                                             
    // listen to alerts from the engine
    while let Some(alert) = alert_rx.next().await {
        match alert {
            Alert::TorrentStats { id, stats } => {
                println!("{}: {:#?}", id, stats);
            }
            Alert::TorrentComplete(id) => {
                println!("{} complete, shutting down", id);
                break;
            }
            Alert::Error(e) => {
              // this is where you'd handle recoverable errors
              println!("Engine error: {}", e);
            }
            _ => (),
        }
    }
                                                                             
    // Don't forget to call shutdown on the engine to gracefully stop all
    // entities in the engine. This will wait for announcing the client's
    // leave to all trackers of torrent, finish pending disk and network IO,
    // as well as wait for peer connections to cleanly shut down.
    engine.shutdown().await?;
                                                                             
    Ok(())
}

项目结构

该项目分为两部分

  • 定义大多数功能的 cratetorrent 库,
  • 以及一个用于通过 CLI 下载归档的 cratetorrent-cli 二进制文件。请注意,但就目前而言,它非常简单,更多地用作演示玩具。

如何运行

在稳定的 Rust 1.48 上进行测试。

需要 Linux!

这是因为文件 I/O 是使用 pwritev(2)preadv(2) API 以获得最佳性能。未来可能支持 Windows 和 Darwin 的 API 适配器,但目前在技术上没有能力这样做。

二进制文件

CLI 二进制文件目前非常基础,但您可以通过直接连接到种子节点或如果种子由 HTTP 追踪器支持来执行下载。

请在存储库根目录下运行以下命令

cargo run --release -p cratetorrent-cli -- \
    --seeds 192.168.0.10:50051,192.168.0.172:49985 \
    --metainfo path/to/mytorrent.torrent \
    --download-dir ~/Downloads

测试

Cratetorrent 经过了充分的测试以确保正确的功能。它包括

  • 一个详尽的内联单元测试套件,
  • 以及各种下载和上传的集成测试,在 集成测试文件夹中。

设计

cratetorrent 的设计文档在 设计文档中。这主要涉及 cratetorrent 的开发者,因为它包含相当底层的描述。

依赖项

~16MB
~325K SLoC