Java 对象流:传输时对象 "change"
Java Object-Stream: Objects "change" while transmission
我正在编写一个基于客户端-服务器的沙盒游戏,但有一个奇怪的错误:
服务器将所有实体保存在一个 ArrayList 中,包括玩家。
它还保存了一个仅包含玩家的 ArrayList,这些玩家也包含在 Entity-ArrayList 中。
对于每个 tick 和每个玩家,服务器都会发送玩家的位置、所有实体的列表以及执行基于客户端的 tick 的命令。我正在使用 Object-Output 和 -InputStreams 进行传输。
服务器发送的消息如下所示:
-> STPOS:{help.DoublePoint@4bfb6f3b} y-coord is 75.25017862499999, I already checked
-> SDENT:{[entity.Player@7dae94a2]} y-coord is 75.25017862499999
-> CLTICK
客户端输入是这样的:
<- STPOS: {help.DoublePoint@49411fd2} y-coord is 75.25017862499999
<- SDENT: {[entity.Player@16f4df75]} y-coord is 60.00158922
<- CLTICK
因此坐标"magically"改变。
ArrayList 的服务器输出是这样工作的:(输出:ObjectOutputStream,实体:ArrayList,Entity 和 ProtocolClass 是我自己的 类)
out.writeObject(new ProtocolClass(PROTOCOL.sendEntities, entities));
客户端输入如下:(in:ObjectInputStream)
ProtocolClass pc = (ProtocolClass) in.readObject();
[...]
[if pc.protocol equals PROTOCOL.sendEntities]
entities = (ArrayList<Entity>) pc.object;
一开始的 y 坐标是“60”,当玩家掉到地上时会增加。 75.25... 是他接触地面时的坐标。 60.0015... 是第一个传输的新 y 坐标。因此它适用于第一个报价单。但也不是一直都这样,经常会停留在60。
只有一个线程使用一个流,所以不会异步调用流。所有 "Queries" 都保存在队列中。我扫描了我的整个项目,但它实际上只一次发送 "SDENT"-Query。
我不知道为什么会这样。将传输的对象转换为 ArrayList 会在 Eclipse 中产生警告:"Unchecked cast"。在其他铸造对象的情况下,情况并非如此。仅转换为 ArrayList 没有区别。
每次要编写同一对象的修订副本时都需要使用ObjectOutputStream.reset()
。请参阅 Javadoc 了解原因。
我正在编写一个基于客户端-服务器的沙盒游戏,但有一个奇怪的错误: 服务器将所有实体保存在一个 ArrayList 中,包括玩家。 它还保存了一个仅包含玩家的 ArrayList,这些玩家也包含在 Entity-ArrayList 中。 对于每个 tick 和每个玩家,服务器都会发送玩家的位置、所有实体的列表以及执行基于客户端的 tick 的命令。我正在使用 Object-Output 和 -InputStreams 进行传输。 服务器发送的消息如下所示:
-> STPOS:{help.DoublePoint@4bfb6f3b} y-coord is 75.25017862499999, I already checked
-> SDENT:{[entity.Player@7dae94a2]} y-coord is 75.25017862499999
-> CLTICK
客户端输入是这样的:
<- STPOS: {help.DoublePoint@49411fd2} y-coord is 75.25017862499999
<- SDENT: {[entity.Player@16f4df75]} y-coord is 60.00158922
<- CLTICK
因此坐标"magically"改变。
ArrayList 的服务器输出是这样工作的:(输出:ObjectOutputStream,实体:ArrayList,Entity 和 ProtocolClass 是我自己的 类)
out.writeObject(new ProtocolClass(PROTOCOL.sendEntities, entities));
客户端输入如下:(in:ObjectInputStream)
ProtocolClass pc = (ProtocolClass) in.readObject();
[...]
[if pc.protocol equals PROTOCOL.sendEntities]
entities = (ArrayList<Entity>) pc.object;
一开始的 y 坐标是“60”,当玩家掉到地上时会增加。 75.25... 是他接触地面时的坐标。 60.0015... 是第一个传输的新 y 坐标。因此它适用于第一个报价单。但也不是一直都这样,经常会停留在60。
只有一个线程使用一个流,所以不会异步调用流。所有 "Queries" 都保存在队列中。我扫描了我的整个项目,但它实际上只一次发送 "SDENT"-Query。
我不知道为什么会这样。将传输的对象转换为 ArrayList 会在 Eclipse 中产生警告:"Unchecked cast"。在其他铸造对象的情况下,情况并非如此。仅转换为 ArrayList 没有区别。
每次要编写同一对象的修订副本时都需要使用ObjectOutputStream.reset()
。请参阅 Javadoc 了解原因。