百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

教程:用golang从零开始手写一个bt下载客户端(2)

cac55 2024-10-17 07:57 21 浏览 0 评论

背景

在上篇中,我们介绍了BT下载的原理,并通过示例搭建了一个p2p网络,了解了BT下载的原理和流程,从这篇文章将开始我们将用golang从零开始手写一个bt下载客户端。在开始动手之前,我们需要得到一个.torrent文件并解析它。

.torrent文件结构

这是一个文本文件,包含了要我们开始下载的全部信息:要分享的文件信息和连接到tracker服务器的信息。它使用bencode编码,就像这样:

d8:announce41:http://bttracker.debian.org:6969/announce7:comment35:"Debian CD from cdimage.debian.org"13:creation datei1573903810e9:httpseedsl145:https://cdimage.debian.org/cdimage/release/10.2.0//srv/cdbuilder.debian.org/dst/deb-cd/weekly-builds/amd64/iso-cd/debian-10.2.0-amd64-netinst.iso145:https://cdimage.debian.org/cdimage/archive/10.2.0//srv/cdbuilder.debian.org/dst/deb-cd/weekly-builds/amd64/iso-cd/debian-10.2.0-amd64-netinst.isoe4:infod6:lengthi351272960e4:name31:debian-10.2.0-amd64-netinst.iso12:piece lengthi262144e6:pieces26800:?????PS?^?? (binary blob of the hashes of each piece)ee

bencode

上面那一堆“乱码”是用一种叫做bencode(发音:bee-encode)的编码方式生成的信息,它不是人类直接可读的,我们需要把它解码才能使用,但它能够高效的编码二进制数据,并且很容易解析。它使用的数据结构和JSON大致相同,共包含4种数据结构:string,integer,list,dictionary。

  • string:用一个数字前缀加冒号表示长度如字符串spam表示为4:spam
  • integer:用i表示开始e表示结束,如数字7表示为i7e
  • list:用l表示开始e表示结束,如['spam',7]表示为l4:spami7ee
  • dictionary:用d表示开始e表示结束,如{spam:7}表示为d4:spami7ee

我们可以使用现成的工具bencode editor来读写.torrent文件


在这个文件里,我们可以找出来tracker服务器地址,创建时间(用unix时间戳表示),文件名、大小以及文件的每个分片。

解析.torrent文件

实现一个bencode也许是很有趣的,但不是我们现在要关注的,我们将使用一个现成的库github.com/jackpal/bencode-go来完成。

package torrentfile

import (
	"bytes"
	"crypto/sha1"
	"fmt"
	"os"

	"github.com/jackpal/bencode-go"
)

type TorrentFile struct {
	Announce    string
	InfoHash    [20]byte
	PieceHashes [][20]byte
	PieceLength int
	Length      int
	Name        string
}

type bencodeInfo struct {
	Pieces      string `bencode:"pieces"`
	PieceLength int    `bencode:"piece length"`
	Length      int    `bencode:"length"`
	Name        string `bencode:"name"`
	NameUtf8    string `bencode:"name.utf-8"`
}

type bencodeTorrent struct {
	Announce string      `bencode:"announce"`
	Info     bencodeInfo `bencode:"info"`
}

func Open(path string) (TorrentFile, error) {
	file, err := os.Open(path)
	if err != nil {
		return TorrentFile{}, err
	}
	defer file.Close()
	bto := bencodeTorrent{}
	err = bencode.Unmarshal(file, &bto)
	if err != nil {
		return TorrentFile{}, err
	}
	return bto.toTorrentFile()
}

func (bto *bencodeTorrent) toTorrentFile() (TorrentFile, error) {
	infoHash, err := bto.Info.hash()
	if err != nil {
		return TorrentFile{}, err
	}
	pieceHashes, err := bto.Info.splitPieceHashes()
	if err != nil {
		return TorrentFile{}, err
	}
	t := TorrentFile{
		Announce:    bto.Announce,
		InfoHash:    infoHash,
		PieceHashes: pieceHashes,
		PieceLength: bto.Info.PieceLength,
		Length:      bto.Info.Length,
		Name:        bto.Info.Name,
	}
	return t, nil
}

为了保持结构的扁平化,我们把一个结构分成了几个,并使用一个工具函数来合并他们。


后面我们将从tracker获取到peers的信息,敬请关注。

相关推荐

14款健身APP蹿红 看看下载最多的是哪款?

Zombies,Run!($3.99,安卓,iOS)如果你的运动理念是:除非有人追,否则绝不跑起来,那么这款APP应该适合你。Zombies,Run!这款程序把单调的跑步过程变身为躲避僵尸的游戏...

微软官方彩蛋庆祝《回到未来》纪念日

2015年10月21日,是MartyMcFly和Brown博士回到未来的时间。现在,这一天真的到了,那么当时影片中展示的一些科技产品究竟有多少实现了呢?作为一家走在技术前沿的公司,日前,微软就在M...

时尚圈最潮同志情侣 帅到没朋友(同志情侣微信头像)

来源:MSN时尚综合|2015-03-0419:45:15男演员ZacharyQuinto(中)与男模MilesMcMillan(右)于纽约街头公开热吻。情人节这个拥有不同起源传说,最早可以...

IE浏览器阻止过期ActiveX控件或将影响网银的使用

IE浏览器网银IE浏览器网银如果经常使用IE浏览器浏览网页的用户,可能都有遇到过浏览器窗口提示安装ActiveX控件的情况,一般情况下用户也是会选择直接安装。ActiveX控件广义上是指微软公司的整...

如何使Microsoft Band连接到WP设备

如果你幸运地购买到了MicrosoftBand,那么恭喜你。现在我们(winbeta)推出了“帮助系列”,那些尚未买到MicrosoftBand的朋友可以了解设备的一些新功能,以及设备的其他关键特...

毕业生不得不看的五大骗局全揭秘(毕业生防骗)

目前,距离高校大学生毕业已不足100天,大部分毕业生都十分忙碌。论文定稿、答辩,参加招聘、面试等成了应届毕业生的头等大事。但随着毕业季的临近,不法分子专门针对毕业生的诈骗高发期也随之来临。360手机安...

菠萝觅生活是O2O应用流量入口最大的供应商

现在主流的传统O2O生活服务,他们其实都有一个共通点,那就是各行其道。打车有快的,滴滴,外卖有饿了么,买机票有去哪儿网…每个APP都有着自己的核心竞争力。而用户呢?既想拥有海量有趣应用,又担心占用过多...

WP8.1版MSN健康应用,现已支持锁屏计步

IT之家(www.ithome.com):WP8.1版MSN健康应用,现已支持锁屏计步@WP之家报道,微软今天已将必应系列应用品牌归为MSN,除此之外,WP8.1版MSN健康和天气应用也获得一些新的...

短信就能传播手机病毒?看完推理惊呆了!

很多人都收到过一种带网址的陌生短信,有的人会点击网址看看,有的还会在好奇心驱使下回复短信。近日《北京新发现》栏目报道了一起离奇的电信诈骗案,事主耿先生的银行卡从未离身,但是在收到一条带网址的陌生短信,...

微软OneClip:我承包了你的剪贴板(微软onedrive云空间)

不久前,Twitter用户WalkingCat曝光了微软一款名为OneClip的应用。这是一款剪贴板应用,根据描述这款应用将覆盖Windows10(包括桌面和移动)、iOS和Android平台,可以...

Windows 10手机应该是什么样?微博用户给出了概念图

随着Windows10发布的不断临近,WindowsPhone的用户对Windows10的旗舰手机的期望也越来越高,我们WP中文网也在微博上发出了同样的问题,搜集用户对Windows10的硬...

云管家出席武汉2015年支付宝O2O生态峰会

2月4日,蚂蚁金服O2O生态峰会在武汉启幕。此次峰会展现了2015年蚂蚁金服在O2O领域的开放思路和策略,以及合作伙伴对O2O的创新观念及思路分享,吸引了武汉近3000名企业大佬、众多创业者、第三方服...

微软将于下周开启Windows开发中心帐号迁移工作

自下周开始微软将启动Windows开发中心的帐号迁移工作。根据WindowsBuildingApps博客透露Windows开发中心帐号迁移工作将会分为几个阶段。首个阶段从下周开始持续到今年7月份...

如何解绑已经合并的MSN账户和Skype账户?

如果您绑定的账户已经充值,建议您把产品消耗完毕后,再进行解绑。当您需要解绑合并的账户时,可登入Skype点卡账户自助操作。输入Skype或MSN账号、密码登录账户:登录后,可在页面左下角选择语言"中文...

微博账号已显示所属MCN机构,成为目前第二个上线该功能的平台

7月25日,多位网友发现,部分微博大V的个人主页已经显示其所属的MCN机构名称,微博也成为目前第二个上线该功能的平台。【来源:中新经纬】声明:此文版权归原作者所有,若有来源错误或者侵犯您的合法权益,您...

取消回复欢迎 发表评论: