2

別のソケットの問題があります。これは私の他の問題と比較して実際にはかなり奇妙です。さて、ObjectOutputStreamを介して一定の速度でデータを送信し、ObjectInputStreamを介してデータを受信するサーバーに接続されたクライアントがあります。プレーヤーの座標、ゲームモードなどを含むプレーヤーオブジェクトで満たされたリストがあります。クライアントがプレーヤーを移動すると、更新された座標がサーバーに送信され、リスト内のそのプレーヤーのオブジェクトが更新されます。さて、更新されるはずです…サーバー側で変更した座標をプリントアウトしていますが、リストをプレイヤーに送ってプリントアウトしても、座標は変わっていません。プレーヤークラスは次のとおりです。

public static class Player implements Serializable {
    private static final long serialVersionUID = 8841477887428285969L;
    public int x, y, gamemode, ID;
    public String name;
    public Player(int x, int y, int gamemode, int ID, String name) {
        this.x = x;
        this.y = y;
        this.gamemode = gamemode;
        this.ID = ID;
        this.name = name;
    }

    public void setPosition(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

サーバーが更新された座標を受け取り、出力の前後を出力する場所:

Package.Client_Server main_packet = (Package.Client_Server) obj;
System.out.println(S00.getPlayerByID(ID).x + ", " + S00.getPlayerByID(ID).y);
S00.getPlayerByID(ID).setPosition(main_packet.x, main_packet.y);
System.out.println(S00.getPlayerByID(ID).x + ", " + S00.getPlayerByID(ID).y);

そして、ここでクライアントはサーバーから送信された独自の座標を出力します。 問題はここにあります...更新された座標はここには表示されませんが、古い座標のままです。私は何か間違ったことをしていますか?リストにはまだオブジェクトが1つしかないため、どこかにオブジェクトを追加するだけではありません...

Package.Server_Client main_packet = (Package.Server_Client) obj;
ID = main_packet.client_ID;
C00.players = main_packet.players;
System.out.println(C00.players.get(ID).x + ", " + C00.players.get(ID).y);
System.out.println(main_packet.players.get(ID).x + ", " + main_packet.players.get(ID).y); 
//I tried printing the list directly from the package as well but it isn't updated either...

ちなみに、リストが保持されているサーバーからクライアントに送信されたパッケージも表示します。

public static class Server_Client implements Serializable {
    private static final long serialVersionUID = 5198487406288606819L;
    public int client_ID;
    public int online;
    public List<Player> players;
    public Server_Client(int client_ID, int online, List<Player> players) {
        this.client_ID = client_ID;
        this.online = online;
        this.players = players;
    }
}

私の全体的な問題は、更新された座標がサーバー側のプレーヤーのリストにあることですが、リストがクライアントに送信されると、更新されたデータは更新されなくなります...プロセス全体が開始される前と同じです。これはソケットの動作の問題ですか、それとも小さなエラーでひどく立ち往生していますか?リストはPlayerオブジェクトの配列と交換したので問題にはなりませんが、それでもクライアント側で正しく読み取られません。ヘルプ?

編集:この効果は、別のクライアントがサーバーに接続するときに、リストが更新されていないためにクライアント1がクライアント2を認識できないためにも見られますが、クライアント2は最初にサーバーに接続したときと同じようにクライアント1を認識できます。クライアント1のコンソールは常に彼が接続されている唯一のプレーヤーであると言います(リストには1つのアイテムがあります)が、コンソール2は常に2人のプレーヤーが接続されていると言います(クライアント1が切断されている場合でも)。したがって、リストは更新されていません。では、何がこれを引き起こす可能性がありますか?

そして、これがメソッド'getPlayerByID(int ID)'です:

public static Package.Player getPlayerByID(int ID) {
    for(int i = 0; i < players.size(); i++) {
        if(players.get(i).ID == ID) {
            return players.get(i);
        }
    }
    throw new NoSuchElementException("No player has the ID: " + ID);
}
4

1 に答える 1

7

ObjectOutputStream同じオブジェクト参照を、それを行うために使用している、またはそのオブジェクトの書き込み間でObjectOutputStream.writeUnshared(Object)呼び出すのと同じオブジェクト参照を繰り返しの単一インスタンスに渡す場合は、必ず確認してください。ObjectOutputStream.reset()

これを行わないとObjectOutputStream、オブジェクトはすでに書き込まれていると見なされ、代わりに以前にシリアル化されたフォームへの参照が書き込まれます。これは、最初にオブジェクトを書き込んだときのオブジェクトのシリアル化された状態になります。

于 2012-08-13T21:24:19.930 に答える