2012-02-27 3 views
3

hereに基づいて、byeが送信されると、単純ソケットサーバークライアントが終了します。以下のコードでは、スレッドベースのアプローチを使用して複数のクライアントを受け入れますが、クライアントハンドリングを正常に処理することはできません。nullを繰り返してエラーを処理します。正常に終了するソケットスレッド

上記のリンクの最初の例は、クライアントとサーバーを終了させます。以下のサーバーコードには、「.bye」が受信されたときに切断する手段はありません。私はクライアントが正常にサーバーから切断することを望みます。クライアントから ".bye"を受信すると、サーバーは接続を閉じる必要があります。これはChatServerThreadのSystem.out.println(streamIn.readUTF());で処理する必要があると思いますか?元のコードの履歴を参照し、解答へのフィードバックを反映するように更新

質問:

import java.net.*; 
import java.io.*; 

public class ChatServerThread implements Runnable 
//public class ChatServerThread extends Thread 
{ private Socket   socket = null; 
    private ChatServer  server = null; 
    private int    ID  = -1; 
    private DataInputStream streamIn = null; 
    private DataOutputStream streamOut = null; 

    public ChatServerThread(ChatServer _server, Socket _socket) 
    { server = _server; socket = _socket; ID = socket.getPort(); 
    } 
    public void run() { 
    try { 
     handleClient(); 
    } catch(EOFException eof) { 
     System.out.println("Client closed the connection."); 
    } catch(IOException ioe) { 
     ioe.printStackTrace(); 
    } 
} 

    public void handleClient() throws IOException { 
     boolean done = false; 
     try { 
     System.out.println("Server Thread " + ID + " running."); 
     while (!done) { 
     String nextCommand = streamIn.readUTF(); 
     if(nextCommand.equals(".bye")) { 
      done = true; 
     } else { 
      System.out.println(nextCommand); 
     } 
    } 
    } finally { 
    streamIn.close(); 
    streamOut.close(); 
    socket.close(); 
    } 
    } 
    public void open() throws IOException 
    { 
     streamIn = new DataInputStream(new BufferedInputStream(socket.getInputStre 
am())); 
     streamOut = new DataOutputStream(new BufferedOutputStream(socket.getOutput 
Stream())); 
    } 
    public void close() throws IOException 
    { if (socket != null) socket.close(); 
     if (streamIn != null) streamIn.close(); 
     if (streamOut != null) streamOut.close(); 
    } 
} 

最初のエラーがimplements Runnableによるものです。 2番目はjava.io.*がインポートされているのでわからないので、なぜそれが不平を言うのか分かりません。クライアントはさようならと言ったので

ChatServer.java:34: error: cannot find symbol 
     client.start(); 
      ^
    symbol: method start() 
    location: variable client of type ChatServerThread 
+0

ここで、ChatServerクラスのスレッドインスタンスをnullに設定していますか?クライアント接続を受け入れるコードserverSocket.accept()はループしています。あなたはクライアントの数に等しい固定回数だけループを実行する必要があります。あなたの場合、プログラムはserverSocket.accept()呼び出しでブロックされます。あなたがこのケースを処理する場合、残りのものは機能するはずです。 – JProgrammer

+0

@JProgrammerオリジナルの質問を明確にしました。サーバーが 'readUTF'と一致するステートメントを受け取った後、クライアントを正常に切断しようとしています。無関係な例は含めてはいけません。 – Astron

答えて

3

一般的に、あなたは、サーバをシャットダウンしていない話します。つまり、どのユーザーもサーバーに接続し、制御せずにリモートでシャットダウンすることができます。サーバーのシャットダウンは、サーバーの管理者または所有者が行います。通常は、認証されたsshセッションを通じてサーバー上でコマンドを実行します。 unix/linuxでは、次のコマンドを実行することができます。

service chatserver stop 

これは別のトピックですが、ベストプラクティスの一般的な概要を説明しています。会話が終了したときにクライアントをシャットダウンする場合は、ここをクリックしてください。それは理にかなっています:

次に、次のクライアントにサービスを提供するためにそのスレッドを解放するか、単純にシャットダウンします。 DataInputStreamを使用すると、クライアントが ".bye"を送信せずにソケットを閉じると、EOFExceptionが発生します。したがって、IOExceptionの前にEOFExceptionをキャッチし、単にシャットダウンすることができます。

通知スレッドをサブクラス化しませんでした。代わりに、スレッドプールや何か面白いものを作成したい場合は、将来の柔軟性を高めるRunnableを実装しました。

+0

私は元の質問を明確にしました。私が参照していた例を含めてはいけません。 'ChatServerThread'でクライアントの接続を切断します。 – Astron

+0

私の答えは変更されません。そのコードはクライアントにサービスするためのサーバーのスレッドループです。 tryステートメントをwhileループを囲むように移動しました。例外がスローされると、会話が終了します。通常は、ソケットのストリームから例外を受け取ったときにしたいことです。とにかくストリームを閉じるべきである。 – chubbsondubs

+0

ストリームとソケットを閉じる 'finally'部分を除いて、うまくいきます:' error:unreported exception IOException;捕捉されなければならない、またはスローされると宣言されなければならないstreamIn.close(); '質問コードが更新されました。クライアントが「.bye」を発行すると、クリーンな切断が発生します。ctrl-Cを使用すると、_null_エントリがサーバ端末に表示されます。クライアントとの接続が切断されたときにサーバが何か有用なものを出力する方法はありますか? – Astron

関連する問題