2012-05-05 2 views
0

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

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

@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(); 
    } 
} 

P.S. ObjectOutputStreamをフラッシュする必要はありませんが、テストするだけのアイデアでした。

+0

スレッディングがこのように優れているかどうかはわかりませんが、そのクライアントを処理するスレッドのクライアントにメッセージをエンキューしますが、基本的にはシナリオでも動作するはずです。 (うまくいけば、あなたはまだそのidを受け取っていないクライアントに新しいプレーヤーを送りません)。あなたの送信whieループは、クライアントが読むことができないようにブロックされている可能性があります。書き込み前と書き込み後にprintlnで検証してください。 – eckes

答えて

1

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

+0

それはうまくいった!しかし、なぜ私は各書き込みの後にリセットを呼び出す必要がありますか? –

+0

リセットブロックをストリームの下に送ります。そのため、リーダは次のオブジェクトに対してリセットする必要があります。それをしなければ、読者はちょうど1つの大きなデータを見ているだけです。 – Krrose27

+0

それでは、私が書いた別のプログラムでこの同じ問題が起きたのはなぜですか?ちょうど私がストリームを介して送信しているオブジェクトの種類のためにちょうど愚かな幸運かですか? –

関連する問題