Как я могу декодировать значение пиров в ответе трекера (Bittorent)

Я пытаюсь реализовать битторентный протокол самостоятельно, и у меня есть проблема с декодированием значения «Peers» в ответе трекера с использованием c ++.

Согласование с документацией по протоколу битторента:

сверстники: (двоичная модель) Вместо использования словарной модели, описанной выше, значение peers может быть строкой, состоящей из кратных 6 байт. Первые 4 байта являются IP-адресом, а последние 2 байта являются номером порта. Все в сетевой (big endian) нотации.

Как я могу декодировать эти IP и номер порта с помощью C ++?

Я пробовал этот код, но это не правильно:

void DecodePeers(OrderedMap<std::string, int> &map, const char * buffer, int i)
{
int counter = 0;while (*(buffer + counter) != NULL)
{

//std::vector<TByte> portNum;
short port;

for (int i = counter; i < counter + 4; i++)
{
//*(peerIp + i - counter) = *(buffer + i);
}

counter += 4;

//*(peerIp + 4) = '\0';
char twobytes[2];

twobytes[0] = *(buffer + counter + 0);
twobytes[1] = *(buffer + counter + 1);

unsigned int x;
std::stringstream ss;
ss << std::hex << twobytes[0];
ss >> x;
// output it as a signed type
std::cout << static_cast<int>(x) << std::endl;

port = ((twobytes[1] << 8) | twobytes[0]);
//port = (short) twobytes;
counter += 2;

//std::string str(portNum.begin(), portNum.end());

std::cout << std::endl;

std::cout << port << std::endl ;

char  * bbuffer = new char[100];

for (int i = 0; i < 1; i++) {
//unsigned int inte = (unsigned int)str;(
//_itoa_s((int) *str.c_str(), bbuffer, 100, 10);
//sprintf_s(bbuffer, 50, (const char *) "%d", str.c_str());
}

std::cout << std::endl;
//int port = atoi(portNum);
//map.Insert(str, port);
}

}

Кто-то знает, как я могу перевести эти числа в числовой ответ?

Example of peers value: P^L♠*j.t╤u→πe199711

1

Решение

Я пытался использовать этот код в вашем буфере для декодирования одноранговых протоколов bittorrent

#include <arpa/inet.h>

int main(int argc, char *argv[])
{
char *buf = "P^L♠*j.t╤u→πe199711";
int chunks = strlen(buf) / 6 ;
int offset =  0;
unsigned char *ip;
unsigned short *port;
int recsDone = 0;
while (recsDone++ <= chunks){
ip   = (unsigned char *) buf+offset;
port = (unsigned short *) buf+offset+4;
printf("%s - %d\n",inet_ntoa(*(in_addr*)ip),ntohs(*port));
offset+=6;
}
}

и я получаю это в качестве вывода:

80,94,76,226 — 11892
42.106.46.116 — 12601

Пожалуйста, дайте нам знать, если это работает.

2

Другие решения

Я не работал с этим протоколом, и показанный код немного сбивает с толку. Я не знаю, что такое peerIp, например. Но на основании описания поля в peer_id, https://wiki.theory.org/BitTorrentSpecification#peer_id, Я бы предложил:

#include <arpa/inet.h>
#include <stdint.h>
#include <stdio.h>

uint32_t *peerIPAux;

struct sockaddr_in peer_data;
char str[INET_ADDRSTRLEN];
uint16_t *peer_port_ptr;
uint16_t peer_port;

//Here we need to test if IPv4 address, represented in an integer value is
//actually in network notation or not. First assume what documentation says
//is true (it is in network notation)

//INSIDE THE WHILE LOOP

peerIPAux = (uint32_t *)(buffer + counter);
peer_data.sin_addr.s_addr = ntohl(*peerIPAux); //If this doesn't work try without ntohl

//http://linux.die.net/man/3/inet_ntop

inet_ntop(AF_INET, &(peer_data.sin_addr), str, INET_ADDRSTRLEN); //check error code here

printf("%s\n", str); // or std::cout << str << std::endl;

counter += 4;
peer_port_ptr = (uint16_t *) (buffer + counter);

peer_port = ntohs(*peer_port_ptr);

printf("PORT: %d", peer_port); // in C
....
0

По вопросам рекламы [email protected]