使用Java实现Bittorrent Peer Wire协议

6

关于Bittorrent Peer Wire协议,我有几个问题需要翻译。

我正在使用这篇规范在Java中实现它。

在Peer Wire协议部分中,它说所有整数都是四字节的大端值。据我所知,Java使用大端序。这是否意味着,如果我想发送一个choke消息:

choke:<len=0001><id=0>

我只需向套接字写入1,然后是0吗?

至于我的第二个问题。当请求一个块时,我应该将多个文件视为一个大的连续文件,还是单独处理每个文件?因为块长度不会与文件对齐,所以一个索引可以同时包含一个文件的结尾和另一个文件的开头?

至于我的最后一个问题,当我打开与对等方的连接并发送我的握手消息时,我只是保持请求块或请求然后等一段时间,看看它是否会从我们那里请求某些内容吗?交流是如何进行的?我主要做过HTTP类型的网络编程,在请求后等待响应。但是,如果我不断地请求块,我该如何发送块?

1个回答

8

问题1

如果您正在使用基于流的I/O,则应坚持使用DataInputStreamDataOutputStream来写入原始类型(例如,byteintlong等)的简单方法:

Socket s; // assume this is already connected
DataOutputStream out = new DataOutputStream( s.getOutputStream );
out.writeByte( 1 );
out.writeInt( 0 );
out.flush(); // optional

如果您正在使用非阻塞I/O(例如java.nio包中的类),则请使用 ByteBuffer
Socket s; // assume this is already connected
SocketChannel = s.getChannel();
ByteBuffer buf = ByteBuffer.allocate(8); // two 4-byte integers
buf.put( 1 ).putInt( 0 );
buf.flip();
c.write( buf ); // assuming channel is writable :)

这些方法会自动处理字节序问题。

问题2

(请注意,通常您传输的是片段(blocks),而不是整块文件。我将在此处略过:) )

在发送/接收片段时,最好将文件(或文件)视为连续的,就像您所说的那样。 .torrent 文件在 info 字典中包含有关文件边界的信息。 在 多文件案例 中,每个文件都有路径和长度;单文件案例 有一个可选名称和长度。由于您知道块大小、块数量和总内容长度(所有这些都来自 .torrent 文件),因此可以在接收它们时将块“放在正确的位置”。

一个简单的做法是创建一个与 torrent 大小相等的单个文件。当您接收到一个块时,请将其写入此单个文件内的正确字节偏移量 (有时称为“.downloading”文件)。例如,考虑由两个文件组成的 torrent:

a/b/file1.txt [100 bytes]
a/b/file2.txt [200 bytes]

piece size (pz) = 50 bytes
total size (tz) = 100+200 = 300 bytes
number pieces (np) = 300/50 = 6
file = my_torrent.downloading

假设我们将数据块和字节偏移量从零开始编号。如果你接收到了第一个数据块的所有内容,那么它在my_torrent.downloading中的(起始)字节偏移是多少?它在(1 * pz)=(1 * 50)=50处。第0个数据块在哪里?在(0 * pz)=(0 * 50)=0处。依此类推...
我敢打赌你现在可以想出如何将这个.downloading文件转换为你的种子中的“真实”内容。
问题3
当参与BitTorrent群集时,你同时向多个对等方上传和下载数据块。请思考一下这一点。在你从某个对等方请求一个数据块的同时,另一个对等方可能正在从你那里请求同样的数据块。这与HTTP的语义完全不同,正如你已经指出的那样。因此,直接回答你的问题,其他对等方会向你请求他们感兴趣的数据。 :)
在向同行请求数据块之前,请确保该同行确实拥有您想要的数据块(可以查看位域和have消息),并且您已经遵守了适当的chocking/interested行为。在此基础上,您通常需要按照最稀有优先的顺序从已知同行列表(由跟踪器或DHT告诉您)请求数据。规范讨论了这一点,并且在这里有很多优化和礼貌方面的考虑。(例如tit-for-tat行为)。您可能会注意到规范没有详细说明这些内容。这是因为BitTorrent客户端的许多机密都隐藏在这部分实现中。 :)
希望这能对你有所帮助!

1
请注意,根据规范,id字段是一个字节而不是整数。 - Michael Borgwardt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接