sockaddr
- это общая структура, которая разделяется различными типами сокетов. Для сокетов TCP/IP эта структура становится sockaddr_in
. Для разъемов unix он становится sockaddr_un
.
В идеале вы бы использовали sockaddr_in
вместо sockaddr
.
Но учитывая sockaddr
, чтобы извлечь IP-адрес из него вы могли бы сделать это:
sockaddr foo;
in_addr ip_address = ((sockaddr_in)foo).sin_addr;
or
in_addr_t ip_address = ((sockaddr_in)foo).sin_addr.s_addr;
Если вы посмотрите внутрь sockaddr_in
вы увидите, что первые 2 байта sa_data
являются номер порта. А следующие 4 байта - это IP-адрес.
PS: Обратите внимание, что IP-адрес хранится в сетевом порядке, поэтому вам, возможно, потребуется использовать ntohl
(network-to-host) и htonl
(хост-сеть) для преобразования в/из хоста заказ.
UPDATE
Для IPv6 вещи похожи:
sockaddr foo;
in_addr6 ip_address = ((sockaddr_in6)foo).sin6_addr;
Чтобы получить доступ к отдельным байт, используйте ip_address[0]
... ip_address[15]
.
Внутри struct первые 2 байта sa_data
являются номером порта, следующие 4 байта являются информацией о потоке, и после этого следующие 16 байтов являются IPv6-адресом.
остерегается, однако, что является больше чем sockaddr
, поэтому при литье из sockaddr
в , убедитесь, что адрес действительно адрес IPv6 путем проверки адреса семьи foo.sa_family == AF_INET6
.
Этот вопрос говорит о кодировке - https://stackoverflow.com/questions/1276294/getting-ipv4-address-from-a-sockaddr-structure – sashoalm