如何将sockaddr_in6 :: sin6_addr字节顺序设置为网络字节顺序?

10

我正在开发一个网络应用程序并使用套接字API。

我想设置sockaddr_in6结构的sin6_addr字节顺序。

对于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个回答

16

struct in6_addrs6_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);

基本上,您可以使用此方法强制执行网络顺序(大端)。 - debuti

0
通常情况下,使用其中一个主机名查找例程并使用其结果即可,该结果已经是网络字节顺序。你为什么要处理硬编码的数字IP地址呢?

老实说,我正在开发一个库。访问主机名存在一些限制。 - Amir Saniyan
@Amir Saniyan 有什么限制?整个互联网都使用主机名而不是 IP 地址,并将后者委托给称为 DNS 的数据库。你的情况有什么不同?在任何情况下,你所要做的就是将 IP 地址以八位字节的形式存储,按照你写的顺序相同,并完成工作。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接