网络字节序到主机字节序的转换Java
Network byte order to host byte order conversion Java
我正在通过 jna 使用 windows-dll 与一些加密狗服务器进行通信。 dll提供了三个函数,分别是connect、disconnect和获取dongle的连接状态。连接和断开工作。但是当我查询状态时,设备应该 return 一个我保存到 DWORD 中的 ip 地址。代码类似于,其中 DWORDByReference IpAddress
是一个输出参数:
int AwUsbGetConnectionStatus(String Hub, DWORDByReference IpAddress, IntByReference Status, DWORD Timeout, HANDLE Event);
DWORD value = ipAddress.getValue();
dll 的规范说明:"IpAddress is in host byte order and can be converted to TCP/IP network byte order using the WinSock htonl function."
在另一个线程中,我读到 java 等同于 htonl 是:
static int htonl(int val) {
return ByteBuffer.allocate(4).putInt(val)
.order(ByteOrder.nativeOrder()).getInt(0);
}
但问题是,我得到了奇怪的值。但不知何故,它们确实对应于 ip 地址的假定值。
比如原来的IP是:192.168.102.118
它 returns 1986439360
当我用上面的方法转换它时,它是-1062705546.
但我想正确转换后应该是192168102118
我试过的另一个 IP 地址是:
192.168.102.112
为此我得到 1885776064
当我将其转换为 -106270552
因此原始地址和转换后的 IP 地址之间的差值仍然是 6。我用不同的 Ips 尝试了这个,Ips 之间的差异总是与假定值相匹配。
那么有人知道吗,如果我将值转换为 dll 函数 returns 的方式有问题,或者当我获取 DWORD 参数的值时甚至会出现问题吗?
您需要将十进制值 (-1062705546) 分解为组成它的 4 个字节。如果这样做,您将得到十六进制表示法:
C0 A8 66 76
对应192.168.102.118.
该方法返回的值是正确的。
在 Java 中,所有整数都是有符号的。它没有无符号类型。
对于您的 IP 192.168.102.118,十六进制数为 C0 A8 66 76,转换为有符号整数为 -1062705546
您应该设置 在 将 little-endian 地址放入其中之前的顺序。
并且(从您的评论 "i guess it should be 192168102118 when converted properly" 看来)您想要 dotted-quad 输出;为此,使用字节数组可能更自然:
static byte[] htoip(int ipv4) {
return ByteBuffer.wrap(new byte[4])
.order(ByteOrder.nativeOrder())
.putInt(ipv4)
.array();
}
这个结果适合传给InetAddress.getByAddress()
等
虽然这不是反转 4 个字节的最简单方法,但它使用 ByteOrder.nativeOrder()
使其可移植并且 future-proof.
我正在通过 jna 使用 windows-dll 与一些加密狗服务器进行通信。 dll提供了三个函数,分别是connect、disconnect和获取dongle的连接状态。连接和断开工作。但是当我查询状态时,设备应该 return 一个我保存到 DWORD 中的 ip 地址。代码类似于,其中 DWORDByReference IpAddress
是一个输出参数:
int AwUsbGetConnectionStatus(String Hub, DWORDByReference IpAddress, IntByReference Status, DWORD Timeout, HANDLE Event);
DWORD value = ipAddress.getValue();
dll 的规范说明:"IpAddress is in host byte order and can be converted to TCP/IP network byte order using the WinSock htonl function."
在另一个线程中,我读到 java 等同于 htonl 是:
static int htonl(int val) {
return ByteBuffer.allocate(4).putInt(val)
.order(ByteOrder.nativeOrder()).getInt(0);
}
但问题是,我得到了奇怪的值。但不知何故,它们确实对应于 ip 地址的假定值。
比如原来的IP是:192.168.102.118
它 returns 1986439360
当我用上面的方法转换它时,它是-1062705546.
但我想正确转换后应该是192168102118
我试过的另一个 IP 地址是:
192.168.102.112
为此我得到 1885776064
当我将其转换为 -106270552
因此原始地址和转换后的 IP 地址之间的差值仍然是 6。我用不同的 Ips 尝试了这个,Ips 之间的差异总是与假定值相匹配。 那么有人知道吗,如果我将值转换为 dll 函数 returns 的方式有问题,或者当我获取 DWORD 参数的值时甚至会出现问题吗?
您需要将十进制值 (-1062705546) 分解为组成它的 4 个字节。如果这样做,您将得到十六进制表示法:
C0 A8 66 76
对应192.168.102.118.
该方法返回的值是正确的。 在 Java 中,所有整数都是有符号的。它没有无符号类型。
对于您的 IP 192.168.102.118,十六进制数为 C0 A8 66 76,转换为有符号整数为 -1062705546
您应该设置 在 将 little-endian 地址放入其中之前的顺序。
并且(从您的评论 "i guess it should be 192168102118 when converted properly" 看来)您想要 dotted-quad 输出;为此,使用字节数组可能更自然:
static byte[] htoip(int ipv4) {
return ByteBuffer.wrap(new byte[4])
.order(ByteOrder.nativeOrder())
.putInt(ipv4)
.array();
}
这个结果适合传给InetAddress.getByAddress()
等
虽然这不是反转 4 个字节的最简单方法,但它使用 ByteOrder.nativeOrder()
使其可移植并且 future-proof.