c:以网络字节顺序递增 IPv4 地址的八位字节
c: increment octets of IPv4 address in network byte order
在下面的代码中,addr_min
和addr_max
是表示IPv4地址的32位无符号值,它们是网络字节顺序,即大端格式:
uint32_t addr;
for (addr = addr_min; addr <= addr_max; addr = addr + htonl(1)) {
...
}
所以假设我想遍历地址 1.2.0.0
并逐渐增加第三个和第四个八位字节,从而总共产生 65534 个地址(addr_max
打印时显示 feff0201)。我预计上面的代码会起作用,相反它只将第 4 个八位字节更改为值 0xfe 而从不触及第三个八位字节。
我可能做错了什么?
您不打算对已按网络字节顺序编码的值进行任何算术运算。在这种情况下,您可能只添加到最高位字节。
快速回答是:
uint32_t val_n = htonl(init_val);
val_n += htonl(1);
不等于
uint32_t val = init_val;
val += 1;
uint32_t val_n = htonl(val);
其中 val
和 init_val
是常规主机顺序值,val_n
是网络顺序编码。
网络顺序值不能直接用于算术。您不知道什么值 htonl(1)
会添加到您的值,并且您不知道添加它会导致下一个字节在最低字节达到 255 后翻转。不要将网络顺序值视为数字,将它们视为具有含义的不透明值。
按照主机顺序保存您使用的所有内容,如实际数字:
uint32_t addr;
for (addr = addr_min; addr <= addr_max; addr += 1) {
uint32_t addr_net_order = htonl(addr);
...
}
其中 addr
、addr_min
和 addr_max
都是主机顺序 即 如果 addr_min
应该是 1.2.0.0
, addr_min = 0x01020000
.
在下面的代码中,addr_min
和addr_max
是表示IPv4地址的32位无符号值,它们是网络字节顺序,即大端格式:
uint32_t addr;
for (addr = addr_min; addr <= addr_max; addr = addr + htonl(1)) {
...
}
所以假设我想遍历地址 1.2.0.0
并逐渐增加第三个和第四个八位字节,从而总共产生 65534 个地址(addr_max
打印时显示 feff0201)。我预计上面的代码会起作用,相反它只将第 4 个八位字节更改为值 0xfe 而从不触及第三个八位字节。
我可能做错了什么?
您不打算对已按网络字节顺序编码的值进行任何算术运算。在这种情况下,您可能只添加到最高位字节。
快速回答是:
uint32_t val_n = htonl(init_val);
val_n += htonl(1);
不等于
uint32_t val = init_val;
val += 1;
uint32_t val_n = htonl(val);
其中 val
和 init_val
是常规主机顺序值,val_n
是网络顺序编码。
网络顺序值不能直接用于算术。您不知道什么值 htonl(1)
会添加到您的值,并且您不知道添加它会导致下一个字节在最低字节达到 255 后翻转。不要将网络顺序值视为数字,将它们视为具有含义的不透明值。
按照主机顺序保存您使用的所有内容,如实际数字:
uint32_t addr;
for (addr = addr_min; addr <= addr_max; addr += 1) {
uint32_t addr_net_order = htonl(addr);
...
}
其中 addr
、addr_min
和 addr_max
都是主机顺序 即 如果 addr_min
应该是 1.2.0.0
, addr_min = 0x01020000
.