我一直在使用客户端/服务器,其中客户端是用Java(Android)编写的,服务器是用C ++编写的。我基本上需要能够将数据集传递给它并让它正确地解释数据。
我用Python编写了一个原型,因为我知道它应该在那里看起来像什么。使用struct.pack,它将打包数据,您可以指定它以网络字节顺序(Big Endian)执行此操作。这是我写的原型(这适用于服务器)。
5 def _BuildPDUToTx(pduObj):
6 txData = struct.pack('!i i', pduObj.Src.Type, pduObj.Src.Len) #pduObj.Src.Type: 1
#pduObj.Src.Len: 16
7 txData += pduObj.Src.Value #pduObj.Src.Value: sourceid
8 txData += struct.pack('!i i', pduObj.Dst.Type, pduObj.Dst.Len) #pduObj.Dst.Type: 2
#pduObj.Dst.Len: 14
9 txData += pduObj.Dst.Value #pduObj.Dst.Value: destid
10 txData += struct.pack('!i i i i', pduObj.Metadata.Type, pduObj.Metadata.Len,\ #pduObj.Metadata.Type: 3
11 pduObj.Metadata.Status, pduObj.Metadata.Remaining) #pduObj.Metadata.Len: 16
#pduObj.Metadata.Status: 0
#pduObj.Metadata.Remaining: 0
12 txData += struct.pack('!i i', pduObj.Msg.Type, pduObj.Msg.Len) #pduObj.Msg.Type: 6
#pduObj.Msg.Len: 27
13 txData += pduObj.Msg.Value #pduObj.Msg.Value: This is the message
14 return(txData)
我使用一些示例代码运行它(示例值是旁边的注释),如果我在服务器端设置原始netcat侦听器(仅查看数据的样子),我会得到以下内容。 / p>
0000000 0000 0100 0000 1000 [6f73 7275 6563 6469] *brackets have "sourceid"
0000010 0000 0200 0000 0e00 [6564 7473 6469] 0000 *brackets have "destid"
0000020 0300 0000 1000 0000 0000 0000 0000 0000
0000030 0600 0000 1b00 [6854 7369 6920 2073 6874 *brackets have "This is the message"
0000040 2065 656d 7373 6761 0065]
我尝试过这样做(并使用了Java equivalent of Python's struct.pack?和Using Java's ByteBuffer to replicate Python's struct.pack的建议)。
我使用了以下代码:
client = new Socket(server, port);
ObjectOutputStream dos = new ObjectOutputStream(new BufferedOutputStream(client.getOutputStream()));
ByteBuffer buffer = ByteBuffer.allocate(1000);
dos.writeInt(Src.Type); // int value 1
dos.writeInt(Src.Len); // int value 16
dos.writeUTF(Src.Value); // String value "sourceid"
dos.writeInt(Dst.Type); // int value 2
dos.writeInt(Dst.Len); // int value 14
dos.writeUTF(Dst.Value); // String value "destid"
dos.writeInt(Metadata.Type); // int value 3
dos.writeInt(Metadata.Len); // int value 16
dos.writeInt(Metadata.Status); // int value 0
dos.writeInt(Metadata.Remaining); // int value 0
dos.writeInt(Msg.Type); // int value 6
dos.writeInt(Msg.Len); // int value 27
dos.writeUTF(Msg.Value); // String value "this is the message"
dos.flush();
InputStream is = client.getInputStream();
byte[] buf = new byte[Constants.ResponseSize];
is.read(buf, 0, Constants.ResponseSize);
client.close();
但是,我得到以下内容。
0000000 edac 0500 4f77 0000 0100 0000 1000 0800
0000010 [6f73 7275 6563 6469] 0000 0200 0000 0e00 *brackets have "sourceid"
0000020 0600 [6564 7473 6469] 0000 0300 0000 1000 *brackets have "destid"
0000030 0000 0000 0000 0000 0000 0600 0000 1b00
0000040 1300 [6854 7369 6920 2073 6874 2065 656d *brackets have "This is the message"
0000050 7373 6761 0065]
0000055
Java似乎增加了很多额外的东西。就像前两个字节一样,不要放在我放在流中的任何东西。那之后我的值为1(32位)和16(接下来的32位),但之后它在“sourceid”之前有0800。
Java在做什么?我怎样才能让它像python一样包装?
答案 0 :(得分:1)
使用DataOutputStream,而不是ObjectOutputStream。
ObjectOutputStream用于将Java对象从一个JVM发送到另一个JVM,主要由Java对象序列化框架使用。
DataOutputStream以Big Endian编写所有内容。
但是,writeUTF
可能需要小心。根据规范,它预先设置字节序列的长度。这可能是,也可能不是你想要的。