问题描述
||
这个问题已经在这里有了答案:
解决方法
也许输出流代码正在另一个线程中对TransferObject进行序列化,并在服务器中的其他位置对其进行修改后,可以看到播放器位置数组。
尝试在服务器代码中的最后一个for循环之前复制播放器位置数组,并将该副本传递给TransferObject构造函数。
复制阵列还将确保所有客户端线程看到一致的播放器位置集。通过上面显示的同步,播放器的位置可以在最终for循环的迭代之间改变。
,您发生了太多事情。您需要隔离并测试各个部分,以使自己确信其中不包含问题。在我看来,要验证的第一件事是TransferObject的序列化。
您可以使用这样的代码来简单地测试对象的序列化/反序列化
import java.io.*;
public static Object testSerialization(Object inObj)
throws IOException,ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(inObj);
// Ensure everything is written to the stream.
oos.close();
ByteArrayInputStream bais =
new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}
使用此方法和一些单元测试来证明它是可以的。
我怀疑问题出在TransferObject中。您正在传递对构造函数中数组的引用,然后继续使用它。它是易变的,如果在序列化TransferObject时有人弄乱了该数组,则会发生不良情况。在我看来,TransferObject应该确实是不可变的:
import java.io.Serializable;
import java.util.Arrays;
public class TransferObject implements Serializable {
/** You should really have this for efficiency */
private static final long serialVersionUID = 1L;
private final int playerId; //to be sent in forst data send to tell client which player they are
private final int turnNow; // ID of who\'s go it is now
private final int command; //0 = initialise,1=game update,2=roll,3=end game
private final int[] playerLoc;
public TransferObject(int playerId,int command,int[] playerLoc) {
this.playerId = playerId;
this.command = command;
this.playerLoc = Arrays.copyOf(playerLoc,playerLoc.length);
}