网络字节顺序到主机字节顺序的转换Java



我通过jna使用windows dll与一些加密狗服务器进行通信。dll提供了三个功能,分别是连接、断开和获取加密狗的连接状态。连接和断开工作。但当我查询状态时,设备应该返回一个ip地址,我将其保存到DWORD中。代码类似于,其中DWORDByReference IpAddress是一个out参数:

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地址的假定值相对应
例如,当原始Ip为:192.168.102.118时
它返回1986439360
,当我用上面的方法转换它时,它是-1062705546。
但我想如果转换正确,它应该是192168102118

我尝试的另一个Ip地址是:192.168.102.112为此我得到了1885776064当我把它转换成-106270552

因此,对于原始地址和转换后的值,Ip地址之间的差值仍然是6。我用不同的Ips尝试了这个,Ips之间的差异总是与假设的值相匹配。那么,有人知道吗,如果我转换dll函数返回的值的方式有问题,或者当我获得DWORD参数的值时可能会有问题?

在放入小端地址之前,您应该设置顺序

看起来(从你的评论"我想正确转换后应该是192168102118"),你想要虚线四元输出;为此,使用字节数组可能更自然:

static byte[] htoip(int ipv4) {
return ByteBuffer.wrap(new byte[4])
.order(ByteOrder.nativeOrder())
.putInt(ipv4)
.array();
}

该结果适用于传递给InetAddress.getByAddress()

虽然这不是反转4个字节的最简单方法,但它对ByteOrder.nativeOrder()的使用使它具有可移植性和未来可验证性。

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

C0 A8 66 76

对应于192.168.102.118。

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

对于您的IP 192.168.102.118,十六进制数为C0 A8 66 76,转换为带符号整数为-1062705546

最新更新