Как установить порядок байтов sockaddr in6::sin6 addr в порядок байтов сети?
Я разрабатываю сетевое приложение и использую API сокетов.
Я хочу установить порядок байтов sin6_addr структуры sockaddr_in6.
для 16 бит или 32 бит переменных, это просто: с помощью htons или htonl:
// IPv4
sockaddr_in addr;
addr.sin_port = htons(123);
addr.sin_addr.s_addr = htonl(123456);
но для 128-битных переменных я не знаю, как установить порядок байтов в сетевом порядке байтов:
// IPv6
sockaddr_in6 addr;
addr.sin6_port = htons(123);
addr.sin6_addr.s6_addr = ??? // 16 bytes with network byte order but how to set?
некоторые ответы могут использовать htons для 8 раз (2 * 8 = 16 байт) или использовать htonl для 4 раз( 4 * 4 = 16 байт), но я не знаю, какой путь правильный.
спасибо.
2 ответов
на s6_addr
член struct in6_addr
определено как:
uint8_t s6_addr[16];
так как это массив uint8_t
, а не один 128-битный целочисленный тип, проблема endianness не возникает: вы просто копируете из своего источника uint8_t [16]
массив к месту назначения. Например, Скопировать в адрес 2001:888:0:2:0:0:0:2
вы используете:
static const uint8_t myaddr[16] = { 0x20, 0x01, 0x08, 0x88, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 };
memcpy(addr.sin6_addr.s6_addr, myaddr, sizeof myaddr);
обычным было бы использовать одну из процедур поиска имени хоста и использовать результат этого, который уже находится в сетевом порядке байтов. Почему вы вообще имеете дело с жестко закодированными числовыми IP-адресами?