Reputation: 1523
I am writing a bittorrent client in C++ that receives a message from a tracker (server) containing several 6 byte strings. The first 4 bytes represent the IP address of a peer and the next 2 bytes represent the port number that the peer is listening on.
I have worked out how to convert the ip bytes into a human readable ip address but am struggling to convert the two bytes representing the port number into an int (or something similar)
Here are my efforts so far:
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;
Upon examination peerport only seems to contain the integer representation of the first byte, how might I be able to fix this?
Thanks in advance :)
Upvotes: 0
Views: 1791
Reputation: 2594
Solution with unions:
union port_extractor
{
BYTE raw_port[2];
unsigned short port_assembled;
};
This will work if your computer endianess is the same as of representation you fetch from the network. Sorry, I dont know how it comes by bittorrent protocol.
If the endianess is the opposite, then the solution you are bound to use is not as nice:
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
Upvotes: -1
Reputation: 234484
I prefer using bitwise operations instead of type punning because it brings no issues with endianness at all (the port number comes as a big endian number, and many systems today are little endian).
int peerport = (portbinary[0] << 8) | portbinary[1];
Upvotes: 3
Reputation: 70412
Since portbinary
is an array of BYTE
, then *portbinary
is equivalent to portbinary[0]
.
A portable way to to achieve your result could be:
peerport = portbinary[0];
peerport = 256*peerport + portbinary[1];
This assumes portbinary
was delivered in network byte order.
Upvotes: 1
Reputation: 283684
Since it seems like the data is aligned, you can just use
peerport = ntohs(*(uint16_t *)(trackers[i]->peersBinary + j * 6 + 4));
Upvotes: 1