当它们重叠时如何将块分成一块
How to divide block in piece when they overlap
一些输入我正在寻找构建一个简单的最小 bittorrent 客户端。
我现在阅读了 2-3 天的协议规范。
这是我到目前为止的理解。假设 torrent 的 片段长度 为 26000 bytes
,并且根据非官方规范 块大小 为 16384
。像这样。
现在根据请求,一块消息看起来像这样
piece 0
block offset 0
block length 16484
到目前为止一切顺利。
现在,对于在片段 0 和片段 1 中重叠的下一个块,请求应该是什么样的
piece 0 ## since the start of byte is in piece 0 use piece 0 instead of piece 1
block offset 16384
block length 16384
现在在接收端我需要重新创建 26000 字节的片段,以便我可以将其与片段(哈希)进行比较以匹配片段的正确性。
我的理解正确吗?
此外,我假设块验证失败,可能是因为第一个块,即块 0(有故障或损坏)
然后我应该重新排队 Block 0 和 Block 1(顺便说一句,这是有效的,也是第 1 部分的一部分)以再次重新传输。
现在突然间,块和块分布变得有点复杂,然后我假设它是。我希望有一个更简单的解决方案。
任何想法
块中的最后一个块可能小于传输块大小。 IE。 26000 - 16384 = 9616
字节应在第二个 PIECE 消息中请求。一旦收到所有 26000
字节,就应该计算 SHA-1 哈希值,并将其与元信息字典 pieces
部分的相应校验和进行比较。如果校验和不匹配,您将无法知道哪个块包含无效数据,应该从该块重新下载所有块。
我的建议是不要依赖作品的某些特定分区,因为:
1) peers 在请求数据时可能使用不同的传输块大小
2) SHA-1 算法是基于块的,消化器最好使用更大的块大小(否则计算会花费更多时间)
一件作品的适当抽象应该是具有以下方法的通用 data range
:
read(from:int, length:int):byte[]
write(offset:int, block:byte[]):()
然后您将能够 read/write 任意数据子范围。
客户普遍接受的最大块大小为16KiB。客户可以自由提出较小的要求。
块通常是 16KiB 的倍数,但当前的规范不要求它(这随 BEP52 改变)并且有些人使用质数或类似的东西来取乐,所以它们确实存在于野外.
块仅存在于您需要多个请求才能获得大于 16KiB 的完整块的意义上。换句话说,块与您决定请求的任何东西都是一样的。您可以请求 500 个字节,然后是 1017 个字节,然后是 13016 个字节,...直到您得到一个完整的片段。它们是片段中的任意细分 - 没有重叠 - 您需要在下载片段开始和完成片段之间进行跟踪。
它们不参与散列,不考虑 HAVE 或 BITFIELD 消息。只有 REQUEST、PIECE、CANCEL 和 REJECT 消息与块有关。除了块,您还可以将它们称为 子片偏移长度元组 或类似的东西。
Will use the more distinct term 'chunk' instead of the ambiguous 'block'.
洪流分片
一块分成几块
一块切一块。
Torrent 在创建时被分成多个部分。使用 Request 消息,一块又被下载的 BitTorrent 客户端进一步分成块。
客户端如何从一块中切出块并不重要,只要没有单个块大于 16 KB(16384 字节)。
划分一块的最简单和最合理的方法是将其划分为尽可能少的块,将其划分为 16 KB 的块,并在必要时让该块的最后一块更小。
The Request message format: <len=0013><id=6><Piece_index><Chunk_offset><Chunk_length>
<Piece_index >
integer specifying the zero-based piece index
<Chunk_offset>
integer specifying the zero-based byte offset within the piece
<Chunk_length>
integer specifying the requested number of bytes
请求块时:
- 整个块必须在
Piece_index
,
指定的块内
即 Chunk_offset
+Chunk_length
必须小于或等于该特定片段的大小*。
Chunk_length
不能大于 16 KB(16384 字节)并且必须至少为 1 个字节
- 收到请求的节点必须有
Piece_index
指定的片段
如果不满足任何条件,接收请求的对等方将关闭连接。
* 除了最后一个是 info 字典中定义的 'piece length'
之外的所有片段。
最后一块的大小可以计算为:
size_last_piece = size_of_torrent - (number_of_pieces - 1) * 'piece length'
一些输入我正在寻找构建一个简单的最小 bittorrent 客户端。 我现在阅读了 2-3 天的协议规范。
这是我到目前为止的理解。假设 torrent 的 片段长度 为 26000 bytes
,并且根据非官方规范 块大小 为 16384
。像这样。
piece 0
block offset 0
block length 16484
到目前为止一切顺利。
现在,对于在片段 0 和片段 1 中重叠的下一个块,请求应该是什么样的
piece 0 ## since the start of byte is in piece 0 use piece 0 instead of piece 1
block offset 16384
block length 16384
现在在接收端我需要重新创建 26000 字节的片段,以便我可以将其与片段(哈希)进行比较以匹配片段的正确性。
我的理解正确吗?
此外,我假设块验证失败,可能是因为第一个块,即块 0(有故障或损坏) 然后我应该重新排队 Block 0 和 Block 1(顺便说一句,这是有效的,也是第 1 部分的一部分)以再次重新传输。
现在突然间,块和块分布变得有点复杂,然后我假设它是。我希望有一个更简单的解决方案。
任何想法
块中的最后一个块可能小于传输块大小。 IE。 26000 - 16384 = 9616
字节应在第二个 PIECE 消息中请求。一旦收到所有 26000
字节,就应该计算 SHA-1 哈希值,并将其与元信息字典 pieces
部分的相应校验和进行比较。如果校验和不匹配,您将无法知道哪个块包含无效数据,应该从该块重新下载所有块。
我的建议是不要依赖作品的某些特定分区,因为: 1) peers 在请求数据时可能使用不同的传输块大小 2) SHA-1 算法是基于块的,消化器最好使用更大的块大小(否则计算会花费更多时间)
一件作品的适当抽象应该是具有以下方法的通用 data range
:
read(from:int, length:int):byte[]
write(offset:int, block:byte[]):()
然后您将能够 read/write 任意数据子范围。
客户普遍接受的最大块大小为16KiB。客户可以自由提出较小的要求。
块通常是 16KiB 的倍数,但当前的规范不要求它(这随 BEP52 改变)并且有些人使用质数或类似的东西来取乐,所以它们确实存在于野外.
块仅存在于您需要多个请求才能获得大于 16KiB 的完整块的意义上。换句话说,块与您决定请求的任何东西都是一样的。您可以请求 500 个字节,然后是 1017 个字节,然后是 13016 个字节,...直到您得到一个完整的片段。它们是片段中的任意细分 - 没有重叠 - 您需要在下载片段开始和完成片段之间进行跟踪。
它们不参与散列,不考虑 HAVE 或 BITFIELD 消息。只有 REQUEST、PIECE、CANCEL 和 REJECT 消息与块有关。除了块,您还可以将它们称为 子片偏移长度元组 或类似的东西。
Will use the more distinct term 'chunk' instead of the ambiguous 'block'.
洪流分片
一块分成几块
一块切一块。
Torrent 在创建时被分成多个部分。使用 Request 消息,一块又被下载的 BitTorrent 客户端进一步分成块。
客户端如何从一块中切出块并不重要,只要没有单个块大于 16 KB(16384 字节)。
划分一块的最简单和最合理的方法是将其划分为尽可能少的块,将其划分为 16 KB 的块,并在必要时让该块的最后一块更小。
The Request message format:
<len=0013><id=6><Piece_index><Chunk_offset><Chunk_length>
<Piece_index >
integer specifying the zero-based piece index<Chunk_offset>
integer specifying the zero-based byte offset within the piece<Chunk_length>
integer specifying the requested number of bytes
请求块时:
- 整个块必须在
Piece_index
,
指定的块内 即Chunk_offset
+Chunk_length
必须小于或等于该特定片段的大小*。 Chunk_length
不能大于 16 KB(16384 字节)并且必须至少为 1 个字节- 收到请求的节点必须有
Piece_index
指定的片段
如果不满足任何条件,接收请求的对等方将关闭连接。
* 除了最后一个是 info 字典中定义的 'piece length'
之外的所有片段。
最后一块的大小可以计算为:
size_last_piece = size_of_torrent - (number_of_pieces - 1) * 'piece length'