2

を使用して小さなサーバーを作成していますjava.nioが、ストレステストをしようとすると、サーバー側で接続がリセットされているというメッセージが表示され続けます。具体的には次のとおりです。

apr_socket_recv: An established connection was aborted by the software in your host machine

最も単純なループに絞り込もうとしましたが、まだ運がありません。100 回ほど接続した後、または 1 回か 2 回接続した直後にエラーが発生する可能性があります。

サーバーループは次のとおりです。

byte[] response = ("HTTP/1.1 200 OK\r\n"
            + "Server: TestServer\r\n"
            + "Content-Type: text/html\r\n"
            + "\r\n"
            + "<html><b>Hello</b></html>").getBytes();

        SocketChannel newChannel = null;
        while (active) {
            try {
                //get a new connection and delegate it.
                System.out.print("Waiting for connection..");
                newChannel = serverSocketChannel.accept();
                System.out.println("ok");

                newChannel.configureBlocking(true);
                newChannel.write(ByteBuffer.wrap(response));
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            finally {
                try {
                    newChannel.close();
                } catch (IOException ex) {
                    Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

        }

書き込みが要求されたすべてのバイトを書き込んでいないかどうかを確認しようとしましたが、一見そうです。興味深いことに、System.gc()それぞれの後に呼び出すとnewChannel.close()問題が解消されます (ただし、その代わりに、非常に遅くなります)。したがって、リリースする必要があるすべてのリソースをリリースしていないか、アプリケーションを一時停止する必要があります..

私はこれで最高の年をすべて失っています。ところで、チャンネルへの書き込みを無視して、接続を受け入れた後に閉じて、問題は解決しません。

4

2 に答える 2

0

よく分かったのでシェアしますね。

アプリを一時停止する必要がありました。単純に速度が速すぎて、クライアントがすべての要求データを書き込む前に接続を閉じていました。修正は、HTTP 要求全体が受信されるまで読み続けることです。D'oh.. 教訓。

于 2011-02-16T21:43:43.513 に答える