0

サーバー/クライアントゲームを書いています。私のクライアントはサーバーにメッセージを送信し、サーバーはそのメッセージをサーバーに接続されている他のすべてのクライアントに配信することになっています。私が抱えている問題は、ois.readObject() (ois は ServerSocket accept() 呼び出しから作成された ObjectInputStream です) を呼び出すと、クライアント側の対応する ObjectOutputStream に書き込む最初の値しか返されないことです。 .

これは、サーバーが接続するクライアントごとに作成するスレッドのコードです。

@Override
public void run() {
    Iterator<ClientThread> itr = null;
    ClientThread ct = null;
    Object recObj = null;
    try {
        oos.writeObject(id);
        oos.flush();

        while(oos != null && ois != null) {
            recObj = ois.readObject();
            System.out.println(recObj);
            if(recObj instanceof Player) {
                System.out.println("[" + id + "] Recieved player from client.");

                player = (Player) recObj;
                Server.playerMap.put(player.getId(), player);

                if(player == null) {
                    System.out.println("Player " + player.getId() + " has joined the server.");
                }

                itr = Server.threadList.iterator();
                while(itr.hasNext()) {
                    ct = itr.next();
                    if(!(ct.id == this.id)) {
                        ct.oos.writeObject(recObj);
                        ct.oos.flush();
                        System.out.println("Sending " + (Player) recObj + " to client " + ct.id + "!");
                    } else {
                        System.out.println("Don't send stuff to " + ct.id + " or we get an infinite loop!");
                    }
                }
            } else {
                System.err.println("Recieved something other than a Player object.");
            }
        }
    } catch (IOException e) {
        System.err.println("[INFO] " + e.getLocalizedMessage());

    } catch (ClassNotFoundException e) {
        System.err.println(e.getLocalizedMessage());
        e.printStackTrace();
    }
    cleanup();
}

このコードは、各クライアントが作成するスレッド用です。

@Override
public void run() {
    Object recObj = null;
    Player newPlayer = null;
    try {
        recObj = client.ois.readObject();
        if(recObj instanceof Integer) {
            client.player = new Player((Integer) recObj);
            client.playerMap.put(client.player.getId(), client.player);
        } else {
            System.err.println("First object recieved from server was not of type Integer.");
            System.err.println("No valid id has been set.");
        }

        while(client.ois != null) {
            recObj = client.ois.readObject();
            if(recObj instanceof Player) {
                newPlayer = (Player) recObj;
                System.out.println("Recieved " + newPlayer + "!");
                client.playerMap.put(newPlayer.getId(), newPlayer); 
            }
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

PS ObjectOutputStream をフラッシュする必要はありませんが、テストするのは単なるアイデアでした。

4

1 に答える 1

1

各書き込み後に ObjectOutputStream で .reset を呼び出します。

于 2012-05-05T01:36:01.627 に答える