-1

エラーや例外がスローされた場合でも、ソケット サーバーを開いたままにしたい

これが私のサーバーです

編集:

public void serveur()
{
     int maxConnectionAllowed=2;
     int port=5000;

    try{

        serveur = new ServerSocket(port);
        serveur.setReuseAddress(true);
        System.out.println("Waiting for connection");

        while (true) {
            synchronized (connectedCount) {
                while (connectedCount.get() >= maxConnectionAllowed) {
                    try {
                        connectedCount.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            Socket socket = serveur.accept();   
            factory.processRequest(socket,connectedCount);
        }           
    }



    catch(SocketException sException){
        System.err.println("Error when a socket connects");

    }   
    catch(IOException ioException){
        System.err.println("Error when reading output/input datas");

    }   
      }
public void run() {
    serveur();
}

たとえば、maxConnection の同時許容数は 2 ですが、3 番目に接続すると、例外がスローjava.net.ConnectException: Connection refused: connectされ、serversocket が閉じられます。場所が利用可能になるまでサーバーを実行し続けたいとします。

編集:

ファクトリーメソッド

public void processRequest(Socket socket,AtomicInteger connectedCount) {
    try
    {

    RequestTreatment requestTreatment= new RequestTreatment(socket,connectedCount);
    Thread threadWorker= new Thread(requestTreatment);
    threadWorker.start();
    }
    finally
    {
        compteurConnexion.incrementAndGet();
        synchronized (connectedCount) {
            connectedCount.notify();
        }
    }

}

}

治療クラスのリクエスト

public RequestTreatment(Socket socket) {
    super();
    this.socket=socket;

}
@Override
public void run() {
            try
            {
            requestTreatment();
            }
             finally
             {
                try {
                socket.getInputStream().close();
                socket.getOutputStream().close();
                socket.close();
                    } catch (IOException e) {
                e.printStackTrace();
                 }

            }
          }



public void treatment() {
        try {
            in = socket.getInputStream();
            out = socket.getOutputStream();

            // do stuff 

        } catch (IOException e) {
            e.printStackTrace();
             } 
        }
    }

どうもありがとうございました

4

2 に答える 2

1
finally{
        try{
            in.close();
            out.close();
            socket.close();
        }
        catch(IOException ioException){
            ioException.printStackTrace();
        }
    }

問題はここにあります。ソケットを処理するために新しいスレッドを開始すると、スレッドがまだ実行されている間に、ソケットを閉じるこの最終ブロックに落ちます。そのため、スレッドは「ソケットが閉じられた」例外に遭遇します。これはではなく、クライアントServerSocket,に受け入れられていることに注意してください。Socketこのコードは、ここではなく、スレッド コードの finally ブロックにある必要があります。

ここに別の問題があります:

public RequestTreatment(Socket socket)
{
    super();
    this.socket=socket;
    threadWorker= new Thread(this);
    threadWorker.start();
}

このコードは、完全に構築される前に「this」をリークします。ここでスレッドを開始するべきではありませんnew RequestTreatment()

于 2012-09-07T05:46:31.153 に答える
1

サーバーに可能なすべての接続を受け入れさせ、それらをある種のリストまたはマップ (できればスレッド セーフ バージョン) に格納し、2 のスレッド プールによって一度に 2 つの接続を処理するメカニズムを持たせることをお勧めします。1 つのプロセスが終了すると、リストから最も古いソケット接続を取得して処理できます。

編集:

3 番目の接続を許可したくないので、コードを次のように変更します。

While(true){
    Socket socket = serveur.accept();
    if(nbClient++< maxConnectionAllowed) factory.processRequest(socket);
    //Else just close the connection and start the loop again
}
于 2012-09-06T13:57:02.967 に答える