简体   繁体   English

Java-序列化对象中的序列化对象问题

[英]Java - Problems with serialized objects within serialized objects

Hey all I'm making a game for funsies and i've solved most problems by researching and reading but now i'm stuck. 嘿,我正在制作一款趣味游戏,并且我已经通过研究和阅读解决了大多数问题,但现在我陷入了困境。

Quick explanation of game: Two clients connect to server and game starts. 游戏快速说明:两个客户端连接到服务器,游戏开始。 Server performs all calculations and sends A serialized GameState object to the clients each cycle. 服务器执行所有计算,并在每个周期向客户端发送一个序列化的GameState对象。 GameState being just a bunch of variables showing the position of players and a some getters/setters. GameState只是一堆变量,显示了玩家的位置和一些获取者/设定者。 This works fine. 这很好。 However, now I have made an arrayList of Missiles in the gamestate, Missiles being a separate object and also serializable. 但是,现在我在游戏状态中创建了一个导弹的arrayList,导弹是一个单独的对象,并且可以序列化。 Both client and server have an identical copy of the GameState class and Missile class. 客户端和服务器都具有GameState类和Missile类的相同副本。

Missiles get added when the client presses space and this DOES get registered by the server. 当客户端按空格键时,将添加导弹,服务器会进行注册。 I made the server print the count of missiles in the server version of gamestate. 我让服务器在游戏状态的服务器版本中打印导弹的数量。 Printing the count of missiles on client side is always zero. 在客户端打印导弹数量始终为零。 Here's some code I've tried to put relevant stuff in only. 这是一些我仅尝试放入相关内容的代码。

Server sending the object to player, player.objectout just writes an object to objectoutputstream 服务器将对象发送给玩家player.objectout只是将一个对象写入objectoutputstream

public void updatePlayerOutput(){
    GameState send = new GameState(gameState);
    leftPlayer.playerObjectOut(send);
    rightPlayer.playerObjectOut(send);
}

The main part of GameState(left out getter and setters). GameState的主要部分(不包括getter和setter)。 Left and right = player1 and player2 左右=玩家1和玩家2

public class GameState implements Serializable {

private double leftX;
private double leftY;
private double rightX;
private double rightY;
private ArrayList<Missile> missiles;

public GameState(){
    missiles = new ArrayList<Missile>();
}

public GameState(GameState game){
    leftX = game.getLeftX();
    leftY = game.getLeftY();
    rightX = game.getRightX();
    rightY = game.getRightY();
    missiles = game.getMissiles();
}

Missile class 导弹级

  public class Missile implements Serializable {

private double x;
private double y;

private double dX;

public Missile(double inX, double inY, double inDX){
    x = inX;
    y = inY;
    dX = inDX;
}

public Missile(Missile inMissile){
    x = inMissile.getX();
    y = inMissile.getY();
    dX = inMissile.getDX();
}

And finally where the client reads. 最后是客户阅读的地方。 panel is a JPanel and uses gamestate to get locations to drawimages 面板是一个JPanel,并使用gamestate获取绘制图像的位置

while(true){
    gameState = (GameState)(ois.readObject());
    panel.setGameState(gameState);
    panel.repaint();
    updateOutput();
    }

Also on a related note(possibly the reason for my main question), in the first section of the code i linked I have to create a completely new GameState object to send. 同样在相关说明(可能是我提出主要问题的原因)上,在我链接的代码的第一部分中,我必须创建要发送的全新GameState对象。 Why is this? 为什么是这样? If I try to just send the gameState variable strightup none of the information is preserved. 如果我尝试仅发送gameState变量strightup,则不会保留任何信息。 Thanks :) 谢谢 :)

So, if I understand correctly, the server has a game state, serializes it, and sends it to the players. 因此,如果我理解正确,则服务器具有游戏状态,将其序列化,然后将其发送给玩家。 The players then modify the content of the game state they received, and you're surprised that the game state on the server doesn't contain the updates. 然后,玩家修改收到的游戏状态的内容,服务器上的游戏状态不包含更新,您会感到惊讶。

That's expected. 那是意料之中的。 Serialization doesn't send a remote reference to the object. 序列化不会发送对该对象的远程引用。 It transforms the object to a sequence of bytes, sends this sequence of bytes, and the object is then reconstructed from the sequence of bytes by the receiver. 它将对象转换为字节序列,发送该字节序列,然后由接收器从字节序列中重建对象。

To make an analogy, sending an object using serialization is like taking a paper document and fax it. 打个比方,使用序列化发送对象就像获取纸质文档并将其传真一样。 Whatever the receiver writes on the received fax won't magically appear on the original document. 接收者在接收到的传真上写的任何内容都不会神奇地出现在原始文档上。

The clients must send the updates to the server if you want the server to be aware of the changes. 如果您希望服务器知道更改,则客户端必须将更新发送到服务器。

Regarding the last part of the question, if I understand correctly, you tried to send the same object multiple times to the same ObjectOutputStream, and the receiver didn't see any difference between the first object state, and the subsequent ones. 关于问题的最后一部分,如果我理解正确,则您尝试将同一对象多次发送到同一ObjectOutputStream,并且接收方没有看到第一个对象状态与后续对象状态之间的任何区别。 This is also expected. 这也是预期的。 Sending the same object a second time only sends a reference to the previously sent object. 第二次发送同一对象仅发送对先前发送的对象的引用。 This is necessary to support graph of objects where the same object is referenced multiple times. 这对于支持多次引用同一对象的对象图是必需的。 You need to call reset() to ... reset the stream and be able to send the new state of an already sent object. 您需要调用reset()来重置流,并能够发送已发送对象的新状态。

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

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