2012-04-05 6 views
0

私は、ゲームロジックがサーバー上でホストされているイベントベースの構造のゲームに取り組んでいます。現在のところ、ちょうど2人の参加者の間で1つのゲームをホストすることができる非常に小さなフィーチャーセットです。私はServerSocketについての様々な質問を読んだことがあり、それらのどれも私の質問に答えません。私はすでに私がObjectInputStreamObjectOutputStreamを利用SeverSocketが受け入れを停止します

私のプロジェクトで

を見ていました。すべてが期待通りに動作しますが(サーバー側とクライアント側の両方で送受信されます)、両方のソケットが登録された後、ServerSocketインスタンスのacceptメソッドは以前と同じコードが呼び出されても永遠にブロックされ続けます。一度ソケットで通信した後に表示される問題でしょうか?

私のサーバーのログには、次を示しています

相手
を待っを知らせるためsocket1するイベントを送信する最初のソケットに
を受け入れる
を受け入れるのを待っ
を受け入れるのを待っている第2のソケット
を受け入れます 両方のソケットに応答を送信
受け入れを待っています(そして永遠にブロックします)

ログにレスポンスイベントが送信されたと表示された場合、ログはクライアント側で正しく受信されて処理されました。クライアントサイドのデバッグ出力は、次のイベントがであることを示しています。間違いなくが送信されました。多分クライアントソケットを閉じないことです(3番目にリンクされた質問に記載されています)?とにかく、私はクライアントのソケットを閉じることができません。

クライアント側コード

public void send(Event e) { 
    try { 
     ObjectOutputStream out = new ObjectOutputStream(
       socket.getOutputStream()); 
     out.writeObject(e); 
     out.flush(); 
     log.debug("sending event... "+e); 
    } 
    catch(IOException ioe) { 
     log.fatal("constructing oos failed", ioe); 
    } 
} 

サーバ側コード短縮する

@Override 
public void run() { 
    running = true; 
    while(running) { 
     try { 
      Socket s = socket.accept(); 
      ObjectInputStream ois = new ObjectInputStream(s.getInputStream()); 
      Event event = (Event) ois.readObject(); 

      try { 
       Event[] response = controller.consume(event); 
       ObjectOutputStream oos = new ObjectOutputStream(sockets[0].getOutputStream()); 
       oos.writeObject(response[0]); 
       oos.flush(); 
       ObjectOutputStream oos2 = new ObjectOutputStream(sockets[1].getOutputStream()); 
       oos2.writeObject(response[1]); 
       oos2.flush(); 
      } 
      catch(...) { 
       // multiple catch clauses for different exceptions 
       // all just logging (nothing passes silently!) 
      } 
    } 
} 

Socket[]アレイへの2つのソケットを割り当てるための方法を除外するが、あるのでた例外はありません、ソケットの動作を維持します。あなたは何が記述された動作を引き起こす可能性があるか考えていますか?前もって感謝します。

+0

[ネットワークチュートリアル](http://docs.oracle.com/javase/tutorial/networking/index.html)を読むことをお勧めします。特に[ソケット・セクション](http://docs.oracle.com/javase/tutorial/networking/sockets/index.html)。 – Jeffrey

+0

私は既にチュートリアルを読んでいます。それはオブジェクトストリームをカバーしておらず、複数のクライアントを扱う際の疑似コードの4行では不十分です。 – phineas

答えて

1

acceptメソッドは、新しい接続のみを受け入れます。サーバーに接続しようとするクライアントが2つしかないため、3回目の起動時にはacceptに無期限にハングアップします。

サイドノート:新しいとObjectOutputStreamを連続して作成する必要はありません。 Socketごとに1つずつ作成し、再利用のために参照を保持することができます。

+0

良いヒント。そのため、構造的側面を変更する必要があります。両方の動作を処理し、新しい接続を登録し、既存の接続を維持するあなたのアプローチは何でしょうか? – phineas

+0

複数のスレッド、または[ノンブロッキングIO](http://www.ibm.com/developerworks/java/library/j-javaio/)を使用してください。 – Jeffrey

関連する問題