假设已经编写了一个不可更改的主机程序,它通过套接字接收这样的 C++ 结构:
#pragma pack(push, 2)
struct Data {
double x;
double y;
double z;
long frameNumber;
};
#pragma pack(pop)
平台:在 Visual Studio 2008 中编译的 C++/32 位 Windows 应用程序
如何从 Java Socket 发送此类数据?我已经尝试用 putDouble() 和 putLong() 填充 ByteBuffer,还有 putInt() 假设 long 为 32 位,但我无法生成有效值。
我还随机生成和发送数据,结构级字节分配看起来很好(我只能随机化一个值,例如 X),但我不能产生确切的值(可能不同的双重表示?),但只能通过发送随机的东西Math.random() * Double.MAX_VALUE;
我可以只在一侧(客户端生成数据)使用 Google 协议缓冲区来解决这个问题吗?
请记住,我无法更改服务器(接收)端
我知道我可以将发送数据转移到 C++ 并使用 JNI,但我正在寻找更简单的解决方案。
我在这里看到至少 2 个可能的问题:
- 字节级的双重表示(如另一侧的 01234567 和 76543210)
- 一个字节中的位表示(如另一侧的 00000001 和 1000000)
这些东西在 C++ 中的 Java 中是什么样子的?
几个小时后,我将为“字节黑客”提供准确的示例数据(发送前的准确 Java 值和 C++ 中接收到的 double 值)
关于服务器不良设计回答
我知道这种实现且不可更改的服务器是糟糕的软件,但这个问题的环境是在“hobbistic 级别”向小型旧应用程序注入一些数据
Java 表示
也许这会帮助一些位级 C++ 专家:
Long.toBinaryString( Double.doubleToRawLongBits( (double) 0 ) );
// 000000000000000000000000000000000000000000000000000000000000000
Long.toBinaryString( Double.doubleToRawLongBits( 1 ) );
// 011111111110000000000000000000000000000000000000000000000000000
Long.toBinaryString( Double.doubleToRawLongBits( 1.1 ) );
// 011111111110001100110011001100110011001100110011001100110011010
Long.toBinaryString( Double.doubleToRawLongBits( 1024 ) );
// 100000010010000000000000000000000000000000000000000000000000000
Long.toBinaryString( Double.doubleToRawLongBits( 1024.1024 ) );
// 100000010010000000000000110100011011011100010111010110001110001
Long.toBinaryString( Double.doubleToRawLongBits( Double.MAX_VALUE ) );
// 111111111101111111111111111111111111111111111111111111111111111