Как установить порядок байтов 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-битным целочисленным типом, проблема порядка не возникает: вы просто копируете из своего источника 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-адресами?

Другие вопросы по тегам