我通过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参数的值时甚至会出现问题?
答案 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();
}
使其具有可移植性和面向未来的能力。