The address->sin_addr
field is an in_addr
struct, which has a single data field s_addr
that is a uint32_t
. So, the address of the s_addr
field happens to be the same address as its containing in_addr
. And while this kind of casting is "safe" to do in this case, it is also wrong to do.
Per the Linux documentation for inet_ntop()
:
AF_INET
`src` points to a `struct in_addr` (in network byte order) which
is converted to an IPv4 network address in the dotted-decimal
format, `"ddd.ddd.ddd.ddd"`. The buffer `dst` must be at least
`INET_ADDRSTRLEN` bytes long.
As you can see, inet_ntop()
expects an in_addr*
pointer for an IPv4 address. The address->sin_addr
field is an actual in_addr
, so you should be passing the address of address->sin_addr
to inet_ntop()
, not the address of address->sin_addr.s_addr
.
An IPv4 address takes up only 15 characters at most, plus a null terminator. So 50
is way overkill for your ip
buffer size. 16
(what INET_ADDRSTRLEN
is defined to be) will suffice.
The correct code should look more like this:
TCPStream::TCPStream(int sd, struct sockaddr_in* address) : msd(sd)
{
char ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(address->sin_addr), ip, sizeof(ip));
m_peerIP = ip;
m_peerPort = ntohs(address->sin_port);
}