Java Object-Stream: объекты меняются при передаче

Я программирую песочницу на основе клиент-сервера, и есть странная ошибка: сервер сохраняет все объекты в ArrayList, включая игроков. Он также сохраняет ArrayList, который содержит только игроков, которые также включены в Entity-ArrayList. Для каждого тика и каждого игрока сервер отправляет позицию игрока, список всех сущностей и команду на выполнение клиентского тика. Я использую 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

При этом координата «волшебным образом» меняется.

Серверный вывод ArrayList работает следующим образом: (out: ObjectOutputStream, entity: ArrayList, Entity и ProtocolClass — мои собственные классы)

out.writeObject(new ProtocolClass(PROTOCOL.sendEntities, entities));

Клиентский ввод следует следующим образом: (в: 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.

Существует только один поток, использующий один поток, поэтому потоки не вызываются асинхронно. Все «запросы» сохраняются в очереди. Я просканировал весь свой проект, но на самом деле он отправляет запрос «SDENT» только один раз.

Я понятия не имею, почему это происходит. Приведение переданных объектов к ArrayList приводит к предупреждению в Eclipse: "Непроверенное приведение". В других случаях литья объектов это не так. Только приведение к ArrayList не имеет значения.


person andrbrue    schedule 26.03.2016    source источник


Ответы (1)


Вам нужно использовать ObjectOutputStream.reset() каждый раз, когда вы хотите написать исправленную копию того же объекта. См. Javadoc, почему.

person user207421    schedule 26.03.2016