网络字节顺序为主机字节顺序转换Java

时间:2017-02-14 16:41:16

标签: java jna

我通过jna使用windows-dll与某些加密狗服务器进行通信。 dll提供三个功能,即连接,断开连接和获取加密狗的连接状态。连接和断开工作。但是当我查询状态时,设备应该返回一个ip-address,我将其保存为DWORD。代码就像,DWORDByReference IpAddress是一个out-parameter:

int AwUsbGetConnectionStatus(String Hub, DWORDByReference IpAddress, IntByReference Status, DWORD Timeout, HANDLE Event); DWORD value = ipAddress.getValue();

dll的规范说明:" IpAddress是主机字节顺序,可以使用WinSock htonl函数转换为TCP / IP网络字节顺序。"

在另一个线程中,我读到了与htonl相当的java是:

static int htonl(int val) { return ByteBuffer.allocate(4).putInt(val) .order(ByteOrder.nativeOrder()).getInt(0); }

但问题是,我得到了奇怪的价值观。但不知何故,它们确实对应于ip-addresses的假定值 例如,当原始的Ip是:192.168.102.118
它返回1986439360
当我用上面的方法转换它时,它是-1062705546 但我认为正确转换后它应该是192168102118

我试过的另一个Ip-Address是: 192.168.102.112 我得到1885776064 当我将其转换为-106270552

因此,对于原始地址和转换后的值,Ip-Addresses之间的差异仍为6。我用不同的Ips尝试了这个,Ips之间的差异总是匹配假设的值。 所以有人知道,如果我转换值的方式有问题,那么dll-function会返回,或者当我得到DWORD参数的值时甚至会出现问题?

3 个答案:

答案 0 :(得分:1)

您需要将十进制值(-1062705546)分解为构成它的4个字节。如果你这样做,你会得到,用十六进制表示法:

C0 A8 66 76

对应于192.168.102.118。

答案 1 :(得分:1)

方法返回的值是正确的。 在Java中,所有整数都是签名的。它没有无符号类型。

对于您的IP 192.168.102.118,HEX编号为C0 A8 66 76,转换为有符号整数为-1062705546

答案 2 :(得分:1)

您应该在之前设置的顺序,将little-endian地址放入其中。

它出现(从您的评论“我猜它应该是192168102118,当正确转换”),你想要点四输出;为此,使用字节数组可能更自然:

3365

此结果适合传递给InetAddress.getByAddress()

虽然这不是反转4个字节的最简单方法,但它使用static byte[] htoip(int ipv4) { return ByteBuffer.wrap(new byte[4]) .order(ByteOrder.nativeOrder()) .putInt(ipv4) .array(); } 使其具有可移植性和面向未来的能力。