Как установить порядок байтов 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-адресами?