简体   繁体   English

棘手的Java序列化问题

[英]Tricky java serialization problem

I have a java server that has to communicate over a TCP socket to an external program written in C. They pass messages back and forth in a message protocol that can't be changed (due to reasons too complicated to go into here). 我有一个Java服务器,必须通过TCP套接字与用C编写的外部程序进行通信。它们以无法更改的消息协议来回传递消息(由于原因太复杂,无法在此处进行介绍)。

The TCP messaging protocol looks roughly like this: TCP消息传递协议大致如下所示:

Header (with message length) -> Message body -> Message CRC 标题(带有消息长度)->消息正文->消息CRC

It seems to me like this is best handled on the java side with an ObjectInputStream/ObjectOutputStream pair and classes that implement java.io.Serializable and have their own writeObject() and readObject() methods. 在我看来,这最好在Java端使用ObjectInputStream / ObjectOutputStream对和实现java.io.Serializable并具有自己的writeObject()和readObject()方法的类进行处理。 The problem is that the only solution I can think of for implementing this messaging protocol involves an extra level of indirection that I want to avoid if at all possible. 问题在于,我能想到的用于实现此消息传递协议的唯一解决方案包括一个额外级别的间接寻址,如果可能的话,我想避免这种情况。

The diffculty is the write portion of the socket and comes because the message length is in front of the message body. 难点是套接字的写入部分,它的出现是因为消息长度在消息主体的前面。 My current solution is to write the message body to a secondary ObjectOutputStream (for the sole purpose of knowing the message length), then writing the header (with length) to the socket, followed by the body then the CRC. 我当前的解决方案是将消息主体写入辅助ObjectOutputStream(仅出于了解消息长度的目的),然后将标头(具有长度)写入套接字,然后是主体,然后是CRC。

My question is this: is there a better way to do this than to use the temporary ObjectOutputStream? 我的问题是:是否有比使用临时ObjectOutputStream更好的方法? That seems pretty wasteful. 这似乎很浪费。

Thanks. 谢谢。

Without more details I'd suggest that you shouldn't be using Object Streams at all they will serialize the Java object to a format that realistically can only been read back into a Java object. 如果没有更多细节,我建议您完全不要使用对象流,因为它们会将Java对象序列化为实际上只能读回到Java对象的格式。 Your C program wouldn't really be able to do anything with what you send it. 您的C程序实际上无法对您发送的内容执行任何操作。

You should probably just be using Byte Array Streams to send the kind of data that the C program can read. 您可能应该只使用字节数组流发送C程序可以读取的数据类型。 You would be able to read the length of the byte array to calculate the CRC. 您将能够读取字节数组的长度来计算CRC。

If you know the maximum size of a message, I'd just give serious consideration to creating a byte array and having a method that writes the message directly into that, leaving space for the length. 如果您知道一条消息的最大大小,那么我将认真考虑创建一个字节数组,并使用一种将消息直接写入其中的方法,以留出一定的长度。

Then, when you've written all the data bytes, go back and put in the length and calculate the CRC. 然后,当您写完所有数据字节后,返回并输入长度并计算CRC。 Then you should be able to push the entire byte array (limited to the actual length) out to the oter end. 然后,您应该能够将整个字节数组(限于实际长度)推出另一端。

If you don't know the maximum size, you can use a vector or one of the other collections. 如果您知道最大大小,则可以使用向量或其他集合之一。 It seems a larger-than-necessary effort to bring in all the serialisation stuff just to ship byte buffers around. 引入所有序列化内容似乎只是为了运送字节缓冲区,这似乎是一项不必要的工作。

Don't serialize objects (unless you want to mess with Externalization which you most likely don't). 不要序列化对象(除非您想弄混您很可能不希望使用的Externalization)。

Just generate the bytes instead, according to the specification and send them without making it more complex. 根据规范,仅生成字节即可发送它们,而不会使其变得更加复杂。

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

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