我在通过套接字发送一些数据时遇到问题,一切正常,直到我尝试发送包含以下内容的类:
int playerId
int command
int[] playerLocations
数据接收没有任何错误,命令和玩家 ID 保留完好。然而int[]
大小正确,但由于某种原因这些值总是重置为 0,我不明白为什么。我也尝试过使用 ArrayList 但出现了同样的问题。
这部分的服务端代码,最后的for循环是重要的部分:
//now loop taking in turns
while (true) {
//first we get the player who's turn it is, and the corresponding thread for their client
int playerTurn = game.getTurnNow();
ClientThreadOnServer AciveClient = clientThreads.get(playerTurn);
//then we send them a message saying it is their go
try {
AciveClient.out.writeObject(new TransferObject(playerTurn, 2, null));
//we wait for them to click roll dice
TransferObject reply = (TransferObject) AciveClient.in.readObject();
//get the command back to roll the dice
int command = reply.getCommand();
int sender = reply.getPlayerId();
// then make a move
if (command == 2 && sender == game.getTurnNow()) {
synchronized (this) { //synchronised to preven concurrent modification
System.out.println("command == 2");
game.rollDice();
game.takeGo();
}
}
//then send the updated game information to everyone
for (int i = 0; i < clientThreads.size(); i++) {
synchronized (this) {
int[] playerLoc = game.getPlayers();
System.out.println("server says:" + playerLoc[i]);
clientThreads.get(i).out.writeObject(new TransferObject(i, 1, playerLoc));
}
}
} catch (Exception ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
其中 system.out 是“服务器说:”打印正确的值,当我调试时,可以在变量部分看到正确的值。
这是正在发送的对象:
import java.io.Serializable;
public class TransferObject implements Serializable {
private int playerId; //to be sent in forst data send to tell client which player they are
private int turnNow; // ID of who's go it is now
private int command; //0 = initialise, 1=game update, 2=roll, 3=end game
private int[] playerLoc;
public TransferObject(int playerId, int command, int[] playerLoc) {
this.playerId = playerId;
this.command = command;
this.playerLoc = playerLoc;
}
public int getCommand() {
return command;
}
public int getPlayerId() {
return playerId;
}
public int getTurnNow() {
return turnNow;
}
public int[] getPlayerLoc() {
return playerLoc;
}
}
和客户端接收部分,命令1是应该打印出正确数据的位,但只打印“...在方 block 0上”
while (true) {
try {
int command = -1; //reset command to something not used in order to prevent confusion
TransferObject transObj = (TransferObject) in.readObject();
command = transObj.getCommand();
if (command == 0) {//initialisation
playerId = transObj.getPlayerId();
} else if (command == 1) {//gui update
for (int i = 0; i < transObj.getPlayerLoc().length; i++) {
//need to have gui stuff here eventually
System.out.println("Player " + i + " on square " + transObj.getPlayerLoc()[i]);
}
} else if (command == 2) {//ask for a roll
JOptionPane.showMessageDialog(null, "Roll the dice?", "It's your go!", JOptionPane.QUESTION_MESSAGE);
TransferObject objOut = new TransferObject(playerId, 2, null); //Send request for roll - NULL COULD BE AN ISSUE
out.writeObject(objOut);
} else if (command == 3) {//end game
JOptionPane.showMessageDialog(null, "Game Over", "Player " + transObj.getPlayerId() + " wins!", JOptionPane.INFORMATION_MESSAGE);
break; //exit loop and game ends
} else {
System.out.println("Data Transfer Error");
}
} catch (Exception ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
抱歉,这里有太多代码,希望有人能理解。如果您需要更多信息,请告诉我。
最佳答案
也许输出流代码正在另一个线程中序列化 TransferObject,并在服务器中其他地方修改后看到玩家位置数组。
尝试在服务器代码中的最终 for 循环之前创建玩家位置数组的副本,并将该副本传递给 TransferObject 构造函数。
复制数组还将确保所有客户端线程看到一组一致的玩家位置。通过上面显示的同步,玩家位置可能会在最终 for 循环的迭代之间发生变化。
关于Java 套接字 - 当我通过连接发送时,ArrayList 丢失信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5639548/