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