BitTorrent 协议规范(BT协议集合)二十

web-specs:Web浏览器中Dat协议的规范[DEFUNCT。 现在使用DEP回购。] 该仓库现已关闭 我们已决定合并到Dat增强提案( )流程中。 Dat协议Web规格 Web浏览器中Dat协议的规范。 状态:刚刚开始! 此存储库中的规范仍在进行中。 动机 现在有多种浏览器计划实施Dat协议: 因此,此存储库将: 记录要由Web浏览器实现的Dat的核心行为。 链接到工作模块和实施。 充当讨论规格和提出更改建议的场所。 由于我们尚未进入任何标准轨道(即WHATWG或W3C),因此此回购协议将使用非正式规范。 目录 会费 建议的更改将在问题和请求中讨论。 达成共识后, datprotocol组织的成员将接受PR并将其合并。 立即下载
作者:小马哥

本篇文章分析 Tracker 类,它在 track.py 文件中。

在分析之前,我们把前几篇文章的内容再回顾一下,以理清思路。

BT的源码,主要可以分为两个部分,一部分用来实现 tracker 服务器,另一部分用来实现BT的客户端。我们这个系列的文章围绕 tracker 服务器的实现来展开。

BT 客户端与 tracker 服务器之间,通过 track HTTP协议进行通信,而BT客户端之间以BT对等协议进行通信。

Tracker 服务器的职责是搜集客户端的信息,并帮助客户端相互发现对方,从而使得客户端之间能够相互建立连接,进而互相能下载所需的文件片断。

在实现 tracker 服务器的时候,首先是通过 RawServer 类来实现网络服务器的功能,然后由 HTTPHandler 类来完成对协议数据的第一层分析。因为 track HTTP 协议是以HTTP协议的形式交互的,所以 HTTPHandler 按照HTTP的协议对客户端的请求进行第一层处理(也就是取得URL和HTTP 消息头),然后把URL和 HTTP消息头进一步交给 Tracker类来进行第二层分析,并把分析的结果按照 HTTP协议的格式封装以后,发给客户端。

Tracker 类对 track HTTP协议做第二层分析,它根据第一层分析后的URL以及HTTP消息头,进一步得到客户端的信息(包括客户端的ip地址、端口、已下载完的数据以及剩余数据等等),然后综合当前所有下载者的情况,生成一个列表,这个列表记录了下载同一个文件的其它下载者的信息(但不是所有的下载者,只是选择一部分),并把这个列表交给 HTTPHandler,由它进一步返回给客户端。

如此,整个 tracker 服务器的实现,在层次上就比较清晰了。

    为了分析 Tracker类,首先要理解“状态文件”。

l       状态文件:

在第一篇文章中,我们说到,要启动一个 tracker 服务器,至少要指定一个参数,就是状态文件。在 Tracker 的初始化函数中,主要就是读取指定的状态文件,并根据该文件做一些初始化的工作。所以必须弄清楚状态文件的作用:

1.       状态文件的作用:

tracker 服务器如果因为某些意外而停止,那么所有的下载者不仅不能继续下载,而且先前所做的努力都前功尽弃。这种情况是不能容忍的,因此,必须保证在 tracker 重新启动之后,所有的下载者还能继续工作。Tracker 服务器周期性的将当前系统中必要的下载状态信息保存到状态文件中,在它因故停止,而后又重新启动的时候,可以根据这些信息重新恢复“现场”,从而使得下载者可以继续下载。

2.       状态文件的格式:

状态文件的信息对应着一个比较复杂的4级嵌套的字典。

要详细分析这个字典类型,必须理解一点:一个 tracker 服务器,可以同时为下载不同文件的几批下载者提供服务。

我们知道,一批下载同一个文件的下载者,它们必然拥有同样的 torrent 文件,它们能根据 torrent 文件找到同一个 tracker 服务器。而下载另一个文件的一批下载者,必然拥有另外一个 torrent 文件,但是这两个不同的 torrent 文件,可能指向的是同一个 tracker 服务器。所以说“一个 tracker 服务器,可以同时为下载不同文件的几批下载者提供服务。”

实际上,那些专门提供 bt 下载的网站,都是架设了一些专门的 tracker 服务器,每个服务器可以同时为多个文件提供下载跟踪服务。

理解了这一点,我们继续分析状态文件的格式。

第一级字典:

在 Tracker 的初始化函数中,有这样的代码,

if exists(self.dfile):

h = open(self.dfile, 'rb')

ds = h.read()

h.close()

tempstate = bdecode(ds)

else:

tempstate = {}

    这段代码是从从状态文件中读取信息,由于读到的是经过 Bencoding 编码后的数据,所以还需要经过解码,解码后就得到一个字典类型的数据,保存到 template 中,这就是第一级字典。它有两个关键字,peers 和 completed,分别用来记录参与下载的peer的信息和已经完成了下载的peer的信息(凡是出现在 completed的peer,也必然出现在 peers中)。这两个关键字对应的数据类型都是字典,我们重点分析 peers 关键字所对应的第二级字典。

第二级字典:

关键字:torrent文件中 info 部分的 SHA hash

数据:第三级字典

一个被下载的文件,唯一的被一个 torrent 文件标识,tracker通过计算torrent文件中 info 部分的 SHA hash,这是一个20字节的字符串,它可以唯一标识被下载文件的信息。第二级字典以此字符串作为关键字,保存下载此文件的下载者们的信息。

第三级字典:

关键字:下载者的 peer id

数据:第四级字典

解释:每个下载者,都创建一个唯一标识自己的20字节的字符串,称为 peer id。第三级字典以次为关键字,保存每个下载者的信息。

第四级字典:

关键字: ip、port、left等

数据:分别保存下载者的 ip地址、端口号和未下载完成的字节数

另外还有两个可选的关键字given ip 和nat,它们是用于 NAT 的,关于NAT的情况,后面会再提到。

理解了这个4级嵌套的字典,对 Tracker 的分析才好继续进行下去。

下面我们挨个看 Tracker 类的成员函数。

l       初始化函数 __init__():

开始是一些参数的初始化,其中比较难理解的有

self.response_size = config['response_size']

self.max_give = config['max_give']

要理解这两个参数,必须看那份更详细的BT协议规范中对“numwant”关键字的解释:

· numwant: Optional. Number of peers that the client would like to receive from the tracker. This value is permitted to be zero. If omitted, typically defaults to 50 peers.

If a client wants a large peer list in the response, then it should specify the numwanted parameter.

意思就是说,默认情况下,tracker 服务器给下载者响应的 peers 个数是 response_size 个,但有时候,下载者可能希望获得更多的 peers 信息,那么它必须在请求中包含 numwant 关键字,并指定希望获得 peers 的个数。例如是 300,tracker 取 300和 max_give中较小的一个,作为返回给下载者的 peers 的个数。

self.natcheck = config['nat_check']

self.only_local_override_ip = config['only_local_override_ip']

这两个参数是和 NAT 相关的,我们终于必须要说到 NAT 了。

我们知道,如果一个 BT 客户端处在局域网中,通过 NAT 之后连到 tracker 服务器的话,那么 tracker 服务器从连接中获得的该客户端的 IP 地址是一个公网IP,如果其它客户端通过这个 IP 试图连接该客户端的话,肯定会被 NAT 拒绝的。

通过一些 NAT 穿越的技术,在某些情况下,可以让一些客户端穿过 NAT,与处在局域网中的客户端建立连接,具体的技术资料我已经贴在论坛上了,大家有兴趣可以去看一看。原来我以为 BT 也用到了一些 NAT 穿越技术,但现在发现并没有,可能是技术实现上比较复杂,而且不能保证在任何情况下都有效的原因吧。

我们来看那份比较详细的协议规范中,对“ip”关键字的解释:

· ip: Optional. The true IP address of the client machine, in dotted quad format. Notes: In general this parameter is not necessary as the address of the client can be determined from the IP address from which the HTTP request came. The parameter is only needed in the case where the IP address that the request came in on is not the IP address of the client. This happens if the client is communicating to the tracker through a proxy (or a transparent web proxy/cache.) It also is necessary when both the client and the tracker are on the same local side of a NAT gateway. The reason for this is that otherwise the tracker would give out the internal (RFC1918) address of the client, which is not routeable. Therefore the client must explicitly state its (external, routeable) IP address to be given out to external peers. Various trackers treat this parameter differently. Some only honor it only if the IP address that the request came in on is in RFC1918 space. Others honor it unconditionally, while others ignore it completely.

在客户端发给 tracker 服务器的请求中,可能包含“ip”,也就是指定自己的 IP 地址。你可能有疑问了,客户端为什么要通知 tracker服务器自己的 ip 地址了?tracker 服务器完全可以从连接中获得这个 ip 啊。嗯,实际的网络情况是非常复杂的,如果客户端是在局域网内通过 NAT 后上网,或者客户端是通过某个代理服务器之后,再与 tracker 服务器建立连接,那么 tracker 从连接中获得的 ip 地址并不是客户端真实的 ip 地址,为了获得真实的ip,必须让客户端主动在协议中通知tracker。因此,就出现了两个 ip 地址,一个是从连接中获得的 ip 地址,我把它叫做“连接ip”,另一个是客户端通过请求传递过来的 ip,我叫它“真实ip”。显然,tracker 应该把客户端的“真实ip”记录下来,并把这个“真实ip”通知给其它下载者。

这个“ip”参数又是可选的,也就是说,如果客户端拥有一个公网的ip,而且并没有通过NAT或者代理,那么,它并不需要传递这个参数,“连接ip”就是“真实ip”。

按协议规发的说法,“ip”这个参数在以下两种情况下有用:

1、客户端可能拥有一个公网IP,但它又是通过一个代理服务器与tracker服务器建立连接的,它需要传递“ip”。

2、客户端在某个局域网中,恰好tracker也在同一个局域网中,。。。(这种情况又会怎么样了?我还没有弄明白 :)

回过头来看 natcheck 和 only_local_override_ip,

natcheck :how many times to check if a downloader is behind a NAT (0 = don't check)

only_local_override_ip:如果从 GET 参数中传递过来的 ip,是一个公网 ip,是否忽略它?它的默认值是 1。

现在还不好理解它的意思,我们看后面代码的时候,再来理解它。

self.becache1 = {}

self.becache2 = {}

self.cache1 = {}

self.cache2 = {}

self.times = {}

这里出现5个字典,其中times 用来,而其它4个字典的作用是什么?

嗯,还是让我们先来看看在“BT移植邮件列表”中,Bram Cohen 发的一个帖子,

There are two new GET parameters for the tracker in the latest release. They are –

key=xxxx - this is like peer id, but it's only known to the client and the tracker. It allows clients to be behind dynamic IP. If a peer announced a key previously, then it's accepted if and only if it gives the same key again. If no key was given, then the fallback is checking that the IP hasn't changed. If the IP has changed, mainline currently will give a peer list but not change any data related to that peer, so that peers behind dynamic IP using old clients will continue to work okay. Currently mainline generates the value associated with key as eight random hex values, and the tracker accepts any string from clients.

compact=1 - when a client sends this, the 'peers' return value is a single string whose length is a multiple of 6 rather than a dict. To extract peer information from the string, chop it into substrings of length 6. For each substring, the first four bytes are the IP and the last two are the port, encoded big-endian. This results in huge bandwidth savings.

Everybody developing ports should implement these keys, they're very useful.

-Bram

BT 在不停的向前发展,所以协议规范也在发展之中,新引入了两个关键字,其中一个是 compact,如果客户端请求中 compact=1,表示紧凑模式,也就是tracker给客户端响应的数据,采用一种比原来更紧凑的形式,这样可以有效的节约带宽。

Becache1 和 cache1用于普通模式,而 becache2和 cache2用于紧凑模式。我们马上能看到它们的初始化操作。

if exists(self.dfile):

h = open(self.dfile, 'rb')

ds = h.read()

h.close()

tempstate = bdecode(ds)

else:

tempstate = {}

if tempstate.has_key('peers'):

self.state = tempstate

else:

self.state = {}

self.state['peers'] = tempstate

self.downloads = self.state.setdefault('peers', {})

self.completed = self.state.setdefault('completed', {})

statefiletemplate(self.state)

这部分代码是读取状态文件,初始化 downloads和completed这两个字典,并检查读取的数据是否有效。

现在,downloads里面是保存了所有下载者的信息,而 completed保存了所有完成下载的下载者的信息。

for x, dl in self.downloads.items():

self.times[x] = {}

    for y, dat in dl.items():

          self.times[x][y] = 0

        if not dat.get('nat',1):

            ip = dat['ip']

          gip = dat.get('given ip')

          if gip and is_valid_ipv4(gip) and (not self.only_local_override_ip or is_local_ip(ip)):

              ip = gip

self.becache1.setdefault(x,{})[y] = Bencached(bencode({'ip': ip, 'port': dat['port'], 'peer id': y}))

          self.becache2.setdefault(x,{})[y] = compact_peer_info(ip, dat['port'])

这里,对 times、becache1、becache2初始化。它们都是2级嵌套的字典,第一级的关键字是 torrent 文件中的 info 部分的 hash,第二级关键字是下载者的 peer id,becache1保存的是一个 Bencached 对象,而 becache2 保存的是一个字符串,它是把 ip和port 组合成的一个字符串。

参数设置完之后,有:

rawserver.add_task(self.save_dfile, self.save_dfile_interval)

add_task() 我们已经见到过好多次了,这表示每隔一段时间,需要调用 save_dfile() 来保存状态文件。

再后面的代码,我没有仔细看了,象 allow_get 和 allowed_dir 等的意义,还需要看相关的代码才能明白,如果你仔细看了这些部分,希望能补充一下。

初始化以后,就是 Tracker 的最重要,也是代码最长的函数: get() 。

l       get():

在第三篇文章中,我们已经看到,在由 HTTPHandler 对 track HTTP协议进行第一层分析之后,就是调用 Tracker::get() 来进行第二层分析的。它的参数是 URL 和 HTTP 消息头。

在这个函数中,首先调用 urlparse() 对 URL 进行解析,例如这样的 URL :

/announce?ip=192.168.112.1&port=9999&left=2000

解析之后,就获得了 path,是announce,还有参数,包括:

ip:192.168.112.1

port:9999

left:2000

然后,根据 path 的不同,分别处理。

一般来说,客户端发给 tracker 的请求中,path 都是 announce,但有时候,第三方可能也想查询一下 tracker 服务器的状态,那么它可以通过其它的 path 来向 tracker 服务器请求,例如 scrape。在一些专门提供 bt 下载的网站上,我们可以看到不停更新的下载者、种子个数等信息,就是用这种方式从 tracker 服务器处获得的。

我们只看 path 是 announce 的情况。

首先是对客户端传递来的参数的有效性进行检查,包括是不是有 info_hash 关键字?ip地址是否合法等等。

然后,

ip = connection.get_ip()

这样得到的 ip ,是根据客户端与 tracker 服务器建立的连接中获取的 ip,就是“连接ip”了。

接下来,

ip_override = 0

if params.has_key('ip') and is_valid_ipv4(params['ip']) and (not self.only_local_override_ip or is_local_ip(ip)):

ip_override = 1

这段代码的意图,是为了判断在随后保存客户端的 ip 地址的时候,是否要用“真实ip”来取代“连接ip”。如果 ip_override 为1,那么就保存“真实ip”,也就是“连接ip”被“真实ip”覆盖(override)了。

分析源码的过程其实就是揣测作者意图的过程,我的揣测是这样的:

如果客户端从请求中传递了“真实ip”,那么对 tracker来说,,既然客户端都已经报告了“真实ip”了,那么当然就保存“真实ip”就好了。可如果“真实 ip ”是个公网 ip,而且only_local_override_ip=1,也就是说,忽略“真实ip”为公网ip的情况,那么,保存的是“连接”ip。

说句实话,为什么要设置 only_local_override_ip 这么一个参数,我还是没有弄明白。

if peers.has_key(myid):

myinfo = peers[myid]

if myinfo.has_key('key'):

if params.get('key') != myinfo['key']:

            return (200, 'OK', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'},

                bencode({'failure reason': 'key did not match key supplied earlier'}))

    confirm = 1

elif myinfo['ip'] == ip:

      confirm = 1

else:

    confirm = 1

这段代码涉及到身份验证吧,我没有仔细看了,关于 “key”的解释,请看上面Bram Cohen的帖子。

接下来,如果验证通过,而且事件不是“stopped”,那么就把客户端的信息保存下来。如果已经存在该客户端的信息,那么就更新一下。注意这里 ip_override 派上了用场,也就是如果覆盖,那么保存的是“真实ip”,否则保存的是“连接ip”。

if port == 0:

peers[myid]['nat'] = 2**30

elif self.natcheck and not ip_override:

to_nat = peers[myid].get('nat', -1)

if to_nat and to_nat < self.natcheck:

NatCheck(self.connectback_result, infohash, myid, ip, port, self.rawserver)

    else:

peers[myid]['nat'] = 0

    第一个 port == 0 的情况,不知道是什么意思?

第二个表示要检查 NAT的情况。大概意思就是 tracker服务器主动用 BT对等协议与该客户端进行握手,如果握手成功,那么说明该客户端是可以被直接连接的。这一点很重要,如果 tracker 服务器无法和客户端直接建立连接的话,那么其它下载者也无法和该客户端建立连接。

这里用到的 NatChecker 类,也是一个 Handler 类,具体细节,大家自己分析吧。

data = {'interval': self.reannounce_interval}

从这到最后,就是根据紧凑模式和普通模式两种不同情况,分别从 becache1或者 becache2中,返回随机的 peers 的信息。

在这里,我们来总结一下 cache1、becache1、cache2、becache2的用处。我感觉 cache1和 cache2 好像没什么作用,因为从代码中没有看到它们两的意义。Becache1和 becache2则分别用于普通模式和紧凑模式情况下,对 peers 的信息进行缓存。它们从状态文件中初始化自己;如果有新的 peer 出现,被添加到这两个缓存中;如果是“stopped”事件,那么从缓存中删除对应的 peer。最后,tracker 根据情况,从其中一个缓存取得随机的 peers 的信息,返回给客户端。

l       connectback_result()

这个函数,用于 NatCheck 类作为回调函数。它根据 tracker 服务器主动与客户端建立连接的结果做一些处理。其中的参数 result,是表示tracker 与客户端建立连接是否成功。如果建立成功,显然对方不在 NAT 后面,否则就是在 NAT 后面了。record['nat'] += 1 这没看懂,为什么不是直接 record['nat'] = 1 ?最后,如果建立连接成功,那么更新一下 becache1 和 becache2。 
trackers每日自动更新地址(包括镜像地址) 用于BT下载的trackers 包括最佳,全部,UDP,http,https等分类 立即下载

相关推荐

ArcGIS符号库下载 | 制图规范、三调、1:1万地形图、土地利用总体规划图.....

最近整理了一些符号库 涉及的类型比较多 包含有三调的(二调的也加上去了),一些点线面符号库,1:1万地形图,1:5万土地利用,土地利用总体规划图

qq_43173805的博客 2万+

最全最好的Tracker地址目录

打开qBittorrent->工具->选项->BitTorrent,下拉到末尾,将trackers粘贴进输入框,并勾选“自动添加以下trackers到新的torrents”,OK。也可以在Trackers界面通过右键->添加新的tracker。打开上面的网站,进入trackers页面,全选→复制。trackers是用来优化下载速度的,多多益善。)下载东西,经常会遇到下载慢,甚至没有速度的情况,添加。可以帮助我们连接到更多的资源节点,我们在使用BT下载器(例如。...

fdw630的博客 5万+

UniApp 与 Taro 深度解析:如何根据项目需求选择最佳跨平台框架?

本文深度对比了UniApp和Taro两大主流跨平台开发框架。UniApp基于Vue生态,提供开箱即用的高效开发体验,尤其适合快速覆盖多端小程序;Taro则根植React范式,架构灵活,便于与现有React生态集成,更适合对性能和原生体验有高要求的复杂项目。文章结合团队技术栈、项目类型及性能需求,为开发者提供了清晰的选型指南。

snow3的博客 204

3 步解决 BT 下载卡 99%:trackerslist 使用教程与选表指南

BT 下载卡在 99%、速度长期停留在几十 KB/s 这类 BT 下载加速问题,多数时候不是带宽不够,而是你的客户端"认识"的同伴太少了。trackerslist 项目每天自动维护一份公共 Tracker 列表,把它导入 qBittorrent、Transmission 等客户端,再配合正确的选表策略,通常就能把同伴数从个位数拉到几十,让卡住的旧种子重新动起来。 ## 为什么下载会卡在 99%

gitblog_00940的博客 174

ROS2中间件选型指南:FastDDS与CycloneDDS零拷贝机制对比与实战

在机器人开发中,通信中间件是连接分布式节点的核心纽带,其性能直接影响系统的实时性与可靠性。DDS作为ROS2默认的通信标准,通过发布订阅模型和QoS策略,为高频大带宽场景提供了灵活的数据分发能力。并行计算与高性能传输的需求,推动了零拷贝技术的演进——从传统序列化到共享内存乃至指针传递,旨在减少数据复制开销、降低延迟。在激光雷达点云、相机图像等场景下,中间件的选型尤为关键。FastDDS凭借与ROS2的深度集成和丰富文档成为入门首选,而CycloneDDS在低延迟和资源占用上表现更优,借助iceoryx实现了

weixin_28726391的博客 252

YOLOv8验证的命令以及计算coco指标

好久不看代码,都不知道怎么验证的了,来记录一下。1、计算coco指标。

毕竟是Shy哥 1481

第十七、十八周微职位:tomcat,MogileFS

1、描述Tomcat的架构;Tomcat组件,分为4类:顶层类组件:包括<Server>元素和<Service>元素,它们位于整个配置文件的顶层;连接器类组件:为<Connector>元素,代表介于客户端与服务器端之间的通信接口,负责将客户端的请求发送给服务器端,并将服务器的响应结果返回给客户端;容器类组件:代表处理客户端请求并生成响应结果...

weixin_33911824的博客 107

基于Matlab与Gurobi的园区微电网风光储协同规划:从独立运营到联合优化的建模实战

本文详细介绍了如何利用Matlab与Gurobi进行园区微电网的风光储协同规划建模实战。通过构建从独立运营到联合优化的数学模型,结合Yalmip工具箱,旨在解决源荷不匹配问题,实现储能系统的最优配置与运行,从而降低总供电成本并提升新能源利用率。

weixin_29053073的博客 140

TrackersListCollection技术内幕:Tracker筛选与名单机制

TrackersListCollection技术内幕:Tracker筛选与名单机制 【免费下载链接】TrackersListCollection ???? Updated daily! A list of popular BitTorrent Trackers! / 每天更新!全网热门 BT Tracker 列表! ...

gitblog_00001的博客 526

CMake接口库实战:如何用add_library的INTERFACE选项管理跨项目依赖

本文深入探讨了CMake中add_library的INTERFACE选项在管理跨项目依赖时的实战应用。通过创建不包含源代码的接口库,开发者可以集中管理头文件路径、编译定义、链接库等公共配置,并将其声明式地传递给依赖目标。文章以构建模块化跨平台网络应用为例,详细展示了如何利用接口库实现配置的集中化、依赖关系的显式化,从而提升大型项目的可维护性和可移植性。

water的专栏 1040

FT2004(D2000)开发实战之AMD R5 230显卡驱动适配

AMD R5 230显卡驱动适配

嵌入式Linux 3199

trackerslist:114个公共Tracker每日自动更新,一次配置让BT下载速度翻倍

用磁力链接下载资源,进度条几十分钟一动不动,速度长期停在几十KB/s——很多人以为是网速或宽带的锅,其实真正的原因是客户端里的公共 Tracker 列表太少了。trackerslist 就是专门维护这份清单的项目:它每天自动筛选全球可用的公共 Tracker,你只需把内容复制进 BT 客户端,下载速度往往立刻改观。整个配置过程五分钟就能完成,不要求任何技术基础。 ## 配置前与配置后:同样的资源

gitblog_00944的博客 464

机器人在果园内行巡检仿真(2D雷达、realsense相机)

DiffBot是一种具有两个轮子的自主差动驱动机器人。它的主要处理单元是一个运行Ubuntu Mate 20.04和ROS 1 (ROS Noetic)中间件的Raspberry pi4b。该存储库包含ROS驱动包、真实机器人的ROS控制硬件接口和模拟DiffBot的配置。修改配置文件orchard_world.launch。

如果想成为中心,那么就到中心去吧。 1311

Tracker 服务器源码分析之四:Tracker 类

Tracker 服务器源码分析之四:Tracker 类 作者:小马哥 日期:2004-6-10   本篇文章分析 Tracker 类,它在 track.py 文件中。 在分析之前,我们把前几篇文章的内容再回顾一下,以理清思路。   BT的源码,主要可以分为两个部分,一部分用来实现 tracker 服务器,另一部分用来实现BT的客户端。我们这个系列的文章围绕 tracker 服务器的实现来展开。

5920

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

bt下载加速 BitTorrent trackers服务器列表

有时候用BT软件下载文件的时候,经常会碰到没速度的情况,这个时候你就需要设置BT Tracker服务器地址了。网上有人专门做了一个列表放在github上面,不定时更新。BitComet软件可以直接添加URL,然后设置启动时更新。 项目地址:https://github.com/ngosang/trackerslist(长期更新) trackers_best (20 tracker...

whatday的专栏 2万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

理解 Linux 动态库加载:LD_LIBRARY_PATH

flyfish

二分掌柜的 347

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

【Linux网络】TCP 服务器并发处理多客户端:从 fork 分发到双重 fork 彻底消灭僵尸进程

拆解 TCP 服务器并发演进链:fork 分发连接、SIGCHLD 循环回收僵尸、双重 fork 交孙进程给 init 收养,并给出模型选型与线上排错对照。

2301_78967866的博客 423

LangGraph 本地 build 频频翻车,最终在服务器跑通流式对话

先说结论:我本地那个,一次都没成功过。三次,三次,全挂在拉镜像上。而顺得像刚上过油。这就很像我高中那辆自行车:骑着能走,一上锁就坏。那天晚上我盯着终端里那行红字看了很久,想的不是技术方案,想的是——为什么同一个工具,可以一边让我觉得自己很行,一边让我觉得自己不太行。

人工智能AI技术 110

【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork

本文详解多进程TCP服务器的实现原理,从单进程并发瓶颈出发,通过fork分离连接接收与服务职责。重点解析文件描述符继承机制、僵尸进程问题及双重fork解决方案,最终构建高效、稳定的多进程服务器模型,并说明服务器重启时可能因端口未释放导致绑定失败的原因。

2402_87731470的博客 2390

自建 Git 服务器和裸仓库差在哪:要能提合并请求

在一台 Linux 上 git init --bare 就能自建 Git 服务器,但它只能推拉代码,没有网页、合并请求、评审和按仓库分配的权限。对照裸仓库和 AngusGit 各自能做什么,再走一遍在 AngusGit 上发起合并请求的最短路径,以及已有裸仓库怎么完整搬过来。

AngusTester 321

轻量点对点定时备份方案:个人文档与服务器文件跨机同步实践

本文探讨了轻量级文件备份场景下的实际需求与解决方案。针对个人文档及小型服务器备份,传统BAT脚本虽易上手,但存在断点续传差、安全缺失、维护困难等短板。作者提出理想方案应具备点对点传输、断点续传、加密传输、版本管理、文件过滤及自动清理等能力。最终选用松鼠备份工具,实现稳定、低运维成本的跨机同步,尤其适合中小型场景,强调“稳定省心”优于复杂功能,是小团队和个人运维的高效之选。

2501_93776716的博客 208

架设一台NFS服务器

3、将/home/tom目录仅共享给192.168.100.136这台主机,并只有用户tom可以完全访问该目录。注意:tom是一个用户目录,并且在客户端创建tom用户一定与服务端的tom用户的uid/gid保持一致。2、开放/nfs/upload目录,为192.168.100.0/24网段主机可以上传目录,并将所有用户及所属的组映射为nfs-upload,其UID和GID均为210。1、开放/nfs/shared目录,供所有用户查询资料。架设一台NFS服务器,并按照以下要求配置。

2401_87595340的博客 235

安徽京准:NTP网络校时服务器在化工厂网络部署要点

安徽京准:NTP网络校时服务器在化工厂网络部署要点

237

Linux epoll 一篇讲透:从 select/poll 到红黑树、LT/ET,再到完整 TCP 服务器

一万个客户端已经连上服务器,眼下只有十个客户端发来了数据。服务器怎样把时间花在这十个连接上?理解这个问题,就抓住了 epoll 的主线。接下来,我们沿着“为什么需要它 → 接口怎么用 → 内核如何实现 → LT/ET 怎么写 → 完整服务器怎么运行”的顺序,把知识连起来。**阅读基础:**了解socketbindlistenaccept的基本用途即可。本文示例面向 Linux,服务器使用 C++17,实验脚本使用 Python 3。

2601_94861874的博客 179

把电脑变成一台“假“GNSS 设备 —— 一个蓝牙 SPP 服务器从零到联调

本文介绍如何用Qt6实现一个蓝牙SPP服务器(H11BtServer),将电脑模拟为一台可被发现的GNSS设备。该服务器支持经典蓝牙SPP协议,注册SDP服务并监听连接,响应AT命令(如AT+DEVINFO),每秒主动推送带正确校验和的NMEA帧($GNPOS/$GGA等),数据基于时间驱动正弦与随机扰动,实现位置、精度等参数动态变化。通过解析行式协议、计算校验和、严格对齐字段顺序,可在无真实硬件情况下联调RTK客户端(如rtklib SDK或手机App),完整验证数据链路。代码结构清晰,参数集中配置,易于

Hi20240217的博客 117

Linux网络编程:彻底理解IO多路复用select!从fd_set位图、读写就绪到手写TCP多客户端字典服务器

在前面的Linux网络编程中,我们已经学习了五种经典I/O模型:其中,我们通过 配合: 将文件描述符设置为非阻塞模式。例如: 这样,在没有数据可读时: 可以立即返回: 并设置: 而不需要让当前线程一直阻塞等待。但是,这又引出了一个新的问题。假设我们的TCP服务器同时连接了100个客户端: 如果使用简单的非阻塞轮询: 服务器就需要不断检查这些Socket。即使其中99个客户端都没有发送任何数据,服务器仍然可能反复调用它们对应的 。显然,这种方式可能产生大量无意义的系统调用。我们真正希望实现的是:能不能让内核

Face_FeaR的博客 651
上一篇: BitTorrent 协议规范(BT协议集合)十九
下一篇: BitTorrent 协议规范(BT协议集合)二一
Pregunta
博客等级 码龄23年 6粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值