3

私は多くのクライアントを持つサーバーを持っています..すべての接続がサーバーに到着します

受け入れられた場合は、スレッドに送信します。

server= serverSocketcht.accept();
new ThrdConv(server).start(); 

ThrdConv スレッドで、入力ストリームと出力ストリームをこの新しい接続に設定しました

    this.OOS=new ObjectOutputStream(server.getOutputStream());
    this.OIS=new ObjectInputStream(server.getInputStream());

次に、到着した接続 (新しいクライアントと呼びましょう) をクライアントのリストに保存します。

  if(isLogged){ // if success login!
      thsisUser= new Clientuser(server,OOS,OIS,Omsg.my_gender,Omsg.userID);
        boolean IsAdded= EIQserver.OnlineusersList.add(this.thsisUser);

すべてが正常に機能し、クライアントはメッセージを送信したり、他のクライアントとチャットしたりできます...

問題は、クライアントが去ったときに、この例外が発生することです:

SEVERE: null
java.io.EOFException
at    
java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2571)

ここに私の休暇機能があります:

 Iterator<Clientuser> iterator = EIQserver.OnlineusersList.iterator();
   if(EIQserver.OnlineusersList.size()>=1)
 Omsg.type= MessageType.Leave;


   sendMessage(OLeavemsg); // tell the partner that I am leaving...

       while (iterator.hasNext()) {
         Clientuser next = iterator.next();
         if (next.ID.equals(OLeavemsg.userID)) 
         {
            next.ClientPort.shutdownInput(); // ClientPort is a socket of this Client
            next.ClientPort.shutdownOutput();
           iterator.remove();// remove the partner
         }
         break;
     }     
       // end leave////////////////////////////////////////////////

接続はリストから削除されますが、上記の例外によりサーバーが停止します...

この複雑な問題を取り除くのを手伝ってください

4

3 に答える 3

0

this.OOS と this.OIS を閉じる必要があります。内部ストリームを再帰的に閉じます。現在のケースでは、クライアントが最初に閉じられるため、外部ストリームが失敗します。Object*Stream を調べることができます。それらの close メソッドは、内部ストリームも閉じます。

于 2013-11-06T11:26:15.077 に答える
0

入力をシャットダウンすると、入力の読み取り時に EOFException が発生しました。それはまさに起こるべきことです。ObjectInputStream を読み取るときは、とにかく EOFException をキャッチする必要があります。ここには「複雑な問題」はまったくありません。例外処理が悪いだけです。

于 2013-11-06T13:00:09.393 に答える
0

ミハイルに感謝します。あなたの答えが解決策の鍵でした。そして、他の読者のために、私はこれをどのように解決したかを説明します:

  • 最初に、OOS、OIS を閉じました...アドバイスどおり..
  • 次に、スレッドを停止します..スレッドを停止するにはどうすればよいですか? :
    • 「Running」という名前の新しいブール変数を宣言し、スレッドのメインループの条件を while(running) に設定し、スレッドのメインループを停止したい場合は running=false を設定しました。これにより、クローズドの使用が停止されます。ストリーム!!
于 2013-11-06T12:21:52.457 に答える