我正在尝试使用从Socket获取的ObjectInputStream和ObjectOutputStream在客户端和服务器之间发送数据包。然而,我在尝试向流中发送一个对象时得到了一些奇怪的结果,我的类结构看起来有点如下:
public class Packet {
public Foo foo;
}
public class Foo {
public float hp = 100;
public double mass = 10;
public void takeDamage(float dmg) {
hp -= dmg;
Packet p = new Packet();
p.foo = this;
//code to send packet to server
}
}
但是我发现服务器在到达时会收到不同的Foo值 - 质量总是正确接收但是hp(每秒最多可以改变50次)未被正确接收(通常会被接收到大约97,不管原始对象的实际hp)。我已经在发送数据包之前检查了hp的值,一旦它到达它似乎只是随机改变,但我认为这可能是因为p.foo是一个指针,就像我反而改为做一个深刻的副本:
p.foo = new Foo();
p.foo.hp = hp;
p.foo.mass = mass;
代码似乎通过hp完全正常发送,因此Streams必须传递未发生变异的对象吗?有没有什么好方法可以在java中强制执行此操作?
答案 0 :(得分:1)
我写的关于ObjectOutpuStream
的所有内容也发生在ObjectInputStream
。
ObjectOutputStream
缓存先前序列化的数据,如果再次序列化相同的实例,则只发送引用而不是整个数据。这使得可以序列化循环数据结构而不会陷入无限循环。我想是因为这就是为什么你会收到一个不同的值(很可能是序列化的第一个值)而不是当前值。
出于同样的原因,您迟早会遇到OutOfMemoryError
,因为ObjectOutputStream
的内部缓存会变得越来越大(您可以调用reset
)。
所以我想你可以通过使用不同于ObjectOutputStream
的东西来改变你的实现,或者在发送一些东西之后你实例化一个新的ObjectOutputStream
(你也需要在接收方那样做)。