0

我正在用 C++ 编写一个 bittorrent 客户端,它从包含几个 6 字节字符串的跟踪器(服务器)接收消息。前 4 个字节表示对等方的 IP 地址,接下来的 2 个字节表示对等方正在侦听的端口号。

我已经研究出如何将 ip 字节转换为人类可读的 ip 地址,但我正在努力将表示端口号的两个字节转换为 int (或类似的东西)

到目前为止,这是我的努力:

BYTE portbinary[2];
unsigned short peerport;

//trackers[i]->peersBinary[j * 6 + 4] is the first byte
portbinary[0] = trackers[i]->peersBinary[j * 6 + 4];
//trackers[i]->peersBinary[j * 6 + 5] is the second byte
portbinary[1] = trackers[i]->peersBinary[j * 6 + 5];
peerport = *portbinary;

经过检查 peerport 似乎只包含第一个字节的整数表示,我该如何解决这个问题?

提前致谢 :)

4

4 回答 4

3

我更喜欢使用按位运算而不是类型双关语,因为它根本不会带来字节序问题(端口号是一个大字节序数,而今天的许多系统都是小字节序)。

int peerport = (portbinary[0] << 8) | portbinary[1];
于 2012-08-09T18:28:22.340 回答
1

由于看起来数据是对齐的,您可以使用

peerport = ntohs(*(uint16_t *)(trackers[i]->peersBinary + j * 6 + 4));
于 2012-08-09T18:23:38.750 回答
1

由于portbinary是 的数组BYTE,则*portbinary等价于portbinary[0]

实现结果的便携式方法可能是:

peerport = portbinary[0];
peerport = 256*peerport + portbinary[1];

这假设portbinary是按网络字节顺序传递的。

于 2012-08-09T18:26:49.593 回答
-1

工会解决方案:

union port_extractor
{
    BYTE raw_port[2];
    unsigned short port_assembled;
};

如果您的计算机字节序与您从网络获取的表示相同,这将起作用。抱歉,我不知道它是如何通过 bittorrent 协议实现的。

如果字节序相反,那么您必须使用的解决方案就不是那么好:

unsigned short port_assembled = (unsigned short)raw_port[first_byte] | ((unsigned short)raw_port[second_byte] << 8);
// first_byte = 0, second_byte = 1 or vice versa 
// depending on source data endianess
于 2012-08-09T18:22:01.263 回答