golang BitTorrent客户端与库插件rain的使用
Golang BitTorrent客户端与库插件rain的使用
rain简介
Rain是一个用Go语言编写的BitTorrent客户端和库。自2019年以来一直在put.io生产环境中运行,每天处理数千个种子。
功能特性
- 核心协议
- 快速扩展
- Magnet链接
- 多Tracker支持
- UDP Tracker
- DHT分布式哈希表
- PEX对等交换
- 消息流加密
- WebSeed
- 快速恢复
- IP黑名单
- RPC服务器和客户端
- 控制台UI
- 创建和读取.torrent文件的工具
安装
在MacOS上可以使用brew安装:
brew install cenkalti/rain/rain
其他系统可以从发布页面获取最新二进制文件。
作为Torrent客户端使用
Rain以单一二进制文件分发。主要使用方式是运行rain server
命令,然后使用rain client <subcommand>
命令操作服务器。服务器包含一个BitTorrent客户端和一个RPC服务器。
rain client
用于向服务器发送命令。还有一个rain client console
命令可以打开基于文本的UI,查看和管理服务器上的种子。运行rain help
查看其他命令。
作为库使用
基本示例
import "github.com/cenkalti/rain/torrent"
// 创建会话
ses, _ := torrent.NewSession(torrent.DefaultConfig)
// 添加magnet链接
tor, _ := ses.AddURI(magnetLink, nil)
// 监视进度
for range time.Tick(time.Second) {
s := tor.Stats()
log.Printf("Status: %s, Downloaded: %d, Peers: %d", s.Status.String(), s.Bytes.Completed, s.Peers.Total)
}
完整示例
package main
import (
"log"
"time"
"github.com/cenkalti/rain/torrent"
)
func main() {
// 创建会话配置
config := torrent.DefaultConfig
config.DataDir = "./downloads" // 设置下载目录
// 创建会话
ses, err := torrent.NewSession(config)
if err != nil {
log.Fatal(err)
}
defer ses.Close()
// 添加magnet链接
magnetLink := "magnet:?xt=urn:btih:..."
tor, err := ses.AddURI(magnetLink, nil)
if err != nil {
log.Fatal(err)
}
// 监听下载完成事件
go func() {
<-tor.NotifyComplete()
log.Println("Download completed!")
}()
// 定期打印状态
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
for range ticker.C {
s := tor.Stats()
log.Printf("Status: %s, Progress: %.2f%%, Downloaded: %d MB, Peers: %d",
s.Status.String(),
float64(s.Bytes.Completed)/float64(s.Bytes.Total)*100,
s.Bytes.Completed/1024/1024,
s.Peers.Total)
if s.Status == torrent.Stopped {
break
}
}
}
配置
所有值都有合理的默认值,因此您可以使用空配置运行Rain。但如果您想自定义其行为,可以使用-config
标志传递YAML配置文件。配置键必须是小写的。
与其他客户端的区别
Rain是put.io使用的主要BitTorrent客户端。它设计用于处理数百个种子,同时使用较低的系统资源。与其他客户端的一个显著区别是Rain为每个种子使用单独的peer端口。这允许Rain为同一私有跟踪器中的多个帐户下载相同的种子,并保持其比例报告正确。
缺少的功能
以下功能未在Rain中实现:
- IPv6 tracker扩展
- DHT的IPv6扩展
- uTorrent传输协议
- 超级种子
- HTTP种子
- Merkle树种子扩展
- uPnP端口转发
- 选择性下载
- 顺序下载
贡献
Rain主要是为满足put.io的特定需求而开发的。由于这一重点目的,与put.io需求不一致的功能请求可能会被拒绝。此外,我们强烈倾向于实现简单性 - 即使技术上更优越,复杂的解决方案通常也不会被接受。在提交问题或拉取请求时,请记住这些准则。
更多关于golang BitTorrent客户端与库插件rain的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang BitTorrent客户端与库插件rain的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang BitTorrent客户端与rain库的使用
rain是一个用Go语言编写的轻量级BitTorrent客户端库,它提供了完整的BitTorrent协议实现,可以用于构建自定义的BitTorrent客户端或集成到其他应用中。
rain库简介
rain库的主要特点包括:
- 纯Go实现,跨平台支持
- 支持DHT网络
- 支持磁力链接
- 支持加密连接
- 轻量级且易于集成
安装rain库
go get -u github.com/cenkalti/rain
基本使用示例
1. 最简单的下载示例
package main
import (
"log"
"time"
"github.com/cenkalti/rain"
)
func main() {
// 创建会话
sess, err := rain.NewSession(rain.Config{
DataDir: "./downloads",
Port: 6881,
DisableDHT: false,
})
if err != nil {
log.Fatal(err)
}
defer sess.Close()
// 添加磁力链接
torrent, err := sess.AddURI(
"magnet:?xt=urn:btih:6a9759bffd5c0af65319979fb7832189f4f3c35d",
nil,
)
if err != nil {
log.Fatal(err)
}
// 等待下载完成
for {
stats := torrent.Stats()
log.Printf("Progress: %.2f%%, Downloaded: %d, Uploaded: %d",
stats.Progress*100, stats.BytesDownloaded, stats.BytesUploaded)
if stats.Completed {
log.Println("Download completed!")
break
}
time.Sleep(time.Second)
}
}
2. 更完整的客户端示例
package main
import (
"fmt"
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/cenkalti/rain"
)
func main() {
// 配置会话
config := rain.Config{
DataDir: "./downloads",
Port: 6881,
DisableDHT: false,
DisableTCP: false,
DisableUTP: false,
DisableUpload: false,
DisableIPv6: false,
EncryptionPolicy: rain.EncryptionPolicyPreferred,
DownloadRateLimit: 0, // 0表示不限速
UploadRateLimit: 0,
}
// 创建会话
sess, err := rain.NewSession(config)
if err != nil {
log.Fatal(err)
}
defer sess.Close()
// 处理命令行参数
if len(os.Args) < 2 {
log.Fatal("Usage: ./client <magnet-uri or torrent-file>")
}
source := os.Args[1]
// 添加下载任务
var torrent *rain.Torrent
if _, err := os.Stat(source); err == nil {
// 如果是文件
torrent, err = sess.AddTorrentFile(source, nil)
} else {
// 如果是磁力链接
torrent, err = sess.AddURI(source, nil)
}
if err != nil {
log.Fatal(err)
}
// 打印基本信息
fmt.Printf("Downloading: %s\n", torrent.Name())
fmt.Printf("InfoHash: %s\n", torrent.InfoHash())
// 设置信号处理,优雅退出
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
// 进度监控循环
ticker := time.NewTicker(3 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
stats := torrent.Stats()
fmt.Printf("\rProgress: %.2f%% | Peers: %d | ↓ %s/s | ↑ %s/s | Seeds: %d",
stats.Progress*100,
stats.ConnectedPeers,
formatBytes(stats.SpeedDownload),
formatBytes(stats.SpeedUpload),
stats.AvailablePeers,
)
if stats.Completed {
fmt.Println("\nDownload completed!")
return
}
case <-sigCh:
fmt.Println("\nShutting down...")
return
}
}
}
// 格式化字节大小为易读格式
func formatBytes(bytes int64) string {
const unit = 1024
if bytes < unit {
return fmt.Sprintf("%d B", bytes)
}
div, exp := int64(unit), 0
for n := bytes / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.1f %ciB", float64(bytes)/float64(div), "KMGTPE"[exp])
}
高级功能
1. 事件监听
// 添加事件监听器
sess.OnTorrentAdded = func(t *rain.Torrent) {
log.Printf("Torrent added: %s", t.Name())
}
sess.OnTorrentRemoved = func(t *rain.Torrent) {
log.Printf("Torrent removed: %s", t.Name())
}
sess.OnTorrentComplete = func(t *rain.Torrent) {
log.Printf("Torrent completed: %s", t.Name())
}
2. 选择性下载文件
// 获取torrent文件列表
torrent, err := sess.AddURI(magnetURI, nil)
if err != nil {
log.Fatal(err)
}
// 等待torrent信息加载完成
for torrent.Stats().Status != rain.StatusDownloadingMetadata {
time.Sleep(time.Second)
}
// 获取文件列表并选择要下载的文件
files := torrent.Files()
for i, file := range files {
fmt.Printf("%d: %s (%.2f MB)\n", i, file.Path, float64(file.Length)/1024/1024)
}
// 选择要下载的文件索引
var selected []int
// ... 根据用户输入设置selected
// 设置文件优先级
for i := range files {
if contains(selected, i) {
torrent.SetFilePriority(i, rain.PriorityNormal)
} else {
torrent.SetFilePriority(i, rain.PriorityNone)
}
}
3. 保存和恢复会话
// 保存会话状态
err = sess.SaveSession()
if err != nil {
log.Printf("Error saving session: %v", err)
}
// 在下次启动时自动恢复之前的下载任务
// 只需要在创建会话时指定相同的DataDir
注意事项
-
端口设置:BitTorrent客户端通常使用6881-6889端口,某些网络可能会阻止这些端口。
-
DHT网络:DHT可以帮助在没有Tracker的情况下找到peer,但在某些网络环境下可能需要禁用。
-
速率限制:合理设置上传/下载速率限制,避免占用过多带宽。
-
磁盘空间:确保有足够的磁盘空间存放下载文件。
-
版权问题:确保下载的内容不侵犯版权。
rain库提供了丰富的配置选项和API,可以根据需要构建功能完善的BitTorrent客户端。以上示例展示了基本用法,更多高级功能可以参考官方文档和源代码。