0

WinServer 2008 マシンに単純なマルチクライアント Java サーバーがあり、正常に動作していますが、一見ランダムな時間 (日) が経過した後、サーバーは接続の受け入れを停止し、その理由がわかりません。

例外をキャッチせず、クラッシュせず、接続を受け入れないだけです。サーバーソケットがGCされていると思ったので、グローバルにしましたが、役に立ちませんでした。何時間も誰も接続しておらず、まだ接続を受け入れておらず、setReuseAddress を true に設定しましたが、同じことを続けているため、TCP の枯渇ではないようです。

再び機能させる唯一の方法は、Java サーバー アプリケーションを再起動することです (マシンを再起動する必要はありません)。

状況に関連する私のコードは次のとおりです。

        try
    {
        ServerSocket srvr = new ServerSocket(PORT);

        while (isAlive)
        {
            Socket skt = srvr.accept();

            this.bw = new PrintWriter(skt.getOutputStream(), true);
            this.br = new BufferedReader(new InputStreamReader(skt.getInputStream()));
            String msg = br.readLine();

                            //process msg

            skt.close();
        }
    }
    catch (Exception e)
    {
        System.out.println("Error");
    }

編集:コードを変更しました

            while (isAlive)
        {
            Socket skt = srvr.accept();
            skt.setSoTimeout(10000);

            acceptConnection(skt);
        }

public void acceptConnection(final Socket skt) throws Exception
{
    Thread discConn = new Thread()
    {
        public void run()
        {
            try
            {
                PrintWriter bw = new PrintWriter(skt.getOutputStream(), true);
                BufferedReader br = new BufferedReader(new InputStreamReader(skt.getInputStream()));
                String msg = br.readLine();
//process msg
                }
            catch (SocketTimeoutException ste)
            {
                //
            }
            catch (SocketException se)
            {
                //
            }
            catch (Exception e)
            {
                System.out.println("ERROR");
            }
            finally
            {
                try
                {
                    skt.close();
                }
                catch (IOException e)
                {
                    System.out.println("ERROR");
                }
            }
            }
    };
    discConn.start();
4

2 に答える 2

1

受け入れループでクライアント I/O をブロックしています。何も送信しない 1 つのクライアントは、システム全体を停止させる可能性があります。受け入れループで行う必要があるのは、接続を受け入れてスレッドを開始することだけです。唯一のブロック操作は、accept() 自体であるべきです。クライアント I/O は別のスレッドで実行する必要があります。

于 2012-09-05T23:40:32.923 に答える
0

ソケットが漏れています。あなたのクローズは例外によってスキップされます。リソースを解放するには、finally ブロックを使用します。

while(...) {
   Socket sckt;
   try {
      sckt = ...
      ...
   } catch(Exception e) {
   } finally {
       sckt.close();
   }
}
于 2012-09-05T04:43:03.823 に答える