繁体   English   中英

Java ByteBuffer-> [NSData字节]到UInt16

[英]Java ByteBuffer -> [NSData bytes] to UInt16

祝大家有美好的一天。

我正在编写基于套接字的客户端服务器应用程序。 服务器是使用Java,客户端-iOS SDK 7上的Objective-C编写的。

我的服务器使用以下代码将数据写入连接的套接字:

//Socket client = new ...;
DataOutputStream out = new DataOutputStream(client.getOutputStream());
// send package
String message = "pings"; // package body
byte bodySize = (byte) message.length();
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(2 + 2 + 1 + bodySize);
buffer.putShort((short) 16); // package ID (2 bytes)
buffer.putShort((short) 7); // package header (2 bytes, bitmask options)
buffer.put(bodySize); // calculate & put body size in 5th byte (1 byte)
buffer.put(message.getBytes()); // put the message to buffer (+5 bytes)

out.write(buffer.array()); // write to stream
out.close(); // close stream

然后,我试图在Objective-C客户端中解析接受的NSData。 这是代码:

- (UInt16)packageIdFromPackageHead:(NSData *)data {
    const void *bytes = [data bytes];
    UInt16 packageId;
    memcpy(&packageId, bytes + 0, 2); // get first 2 bytes, it must be short = 16
    return packageId;
}

但是,在“ packageId”变量中,我的值为“ 4096”。 这是什么? 我的16位十进制值在哪里?

接下来,我试图获取下一个值“ package header”。 我写了以下代码:

UInt16 header;
memcpy(&header, bytes + 2, 2); // skip first 2 bytes, copy next 2 bytes, must be short = 7

我获得了巨大的价值,1792。为什么? 这个数字是什么意思? 我尝试了几个偏移量,+ 2,+ 3-什么也没有。 我无法获得正确的值。 我试图使用一些转换作为

header = CFSwapInt32BigToHost(header);

要么

header = CFSwapInt32HostToBig(header);

这无济于事-转换后每次我得到0。

接下来,当我尝试获取第5个字节时(记住,它包含我们的消息字符串长度)。 这是代码:

UInt8 bodySize;
memcpy(&bodySize, bytes + 4, 1); // get the 5th byte

我得到了价值

'\x05'

这是正确的。

我几乎可以确定输入的NSData *值是正确的。 在这里,您可以看到Xcode的内存转储屏幕截图:

调试模式。 输入NSData *内存转储

哪里有问题? 在服务器代码? 还是在我的客户中阅读代码? 请帮忙,我花了2天的时间找到解决方案,但仍然无法解决。

多亏了Hot Licks!

正确的客户端代码是:

const void *bytes = [data bytes];
UInt16 packageId; // 16-bit value
memcpy(&packageId, bytes + 0, 2); // copy first 2 bytes
packageId = CFSwapInt16BigToHost(packageId); // fix endianness for 16-bit value
return packageId; // now we got correct value

或者,更方便的是,使用以下命令修改服务器上的Java代码:

java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(2 + 2 + 1 + bodySize);
buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN);

进行此修改后,无需使用CFSwapInt ...函数,初始客户端代码即可正常工作。

非常感谢您的帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM