Java 套接字 - 当我通过连接发送时,ArrayList 丢失信息

标签 java sockets

我在通过套接字发送一些数据时遇到问题,一切正常,直到我尝试发送包含以下内容的类:

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/

相关文章:

java - 如何修复 Java 中的 CDC float AWT 框架?

java - 多个不同对象的二维数组

node.js - 如何通过socket.io将数据流传输到客户端

javascript - 带有 Angularjs 的 sockjs - 错误 : INVALID_STATE_ERR

PHP打包二进制数据

java - 听/通知 pgconnection 关闭 java?

java - 每个 Spring Web 应用程序仅加载一次图像

java - 在 JTable 中禁用单元格轮廓

Python 主机名解析非常慢

c - 关于so​​cket编程中这个strncpy函数的一个问题