C++中的BitTorrent Peer Wire消息

nik*_*sdi 2 c++ p2p bittorrent

我正在使用C++开发一个torrent客户端.我无法理解与同行的消息结构.如何使用C++创建简单的握手消息,如何读取响应?问题是我必须发送的数据的结构,然后是我必须阅读的结构.我想向种子发送一个握手消息,发送一个BlockBuf示例.我如何创建BlockBuf的内容?问题是我必须用于消息而不是对等连接的结构...... :(

R. *_*des 6

所以BitTorrent握手由以下顺序组成:

  1. 一个值为19的字节(后面的字符串的长度);
  2. UTF-8字符串"BitTorrent协议"(与ASCII中的相同);
  3. 用于标记扩展的八个保留字节;
  4. torrent信息哈希的20个字节;
  5. 对等ID的20个字节.

因此,您可以从获取足够大的缓冲区来获取握手消息:

const int handshake_size = 1+19+8+20+20;
char handshake[handshake_size];
Run Code Online (Sandbox Code Playgroud)

事先计算偏移量也有助于:

const int protocol_name_offset = 1;
const int reserved_offset = protocol_name_offset + 19;
const int info_hash_offset = reserved_offset + 8;
const int peer_id_offset = info_hash_offset + 20;
Run Code Online (Sandbox Code Playgroud)

然后你只需填写它.

const char prefix = 19;
const std::string BitTorrent_protocol = "BitTorrent protocol";

handshake[0] = prefix; // length prefix of the string
std::copy(BitTorrent_protocol.begin(), BitTorrent_protocol.end(),
          &handshake[protocol_name_offset]); // protocol name
Run Code Online (Sandbox Code Playgroud)

等等其他数据.

然后缓冲区可以直接发送到您将使用的任何网络API.

要阅读回复,请提取缓冲区的各个部分并进行相应验证:

if(reply[0] != prefix) {
    // fail
}
if(!std::equal(BitTorrent_protocol.begin(), BitTorrent_protocol.end(), &reply[protocol_name_offset]) {
    // fail 
}
Run Code Online (Sandbox Code Playgroud)

等等.

不建议直接从网络读取和写入结构,因为您需要完全控制布局,否则消息将格式错误.