apr_socket_recv: установленное соединение было прервано программным обеспечением на вашем хост-компьютере - PullRequest
2 голосов
/ 16 февраля 2011

Я создаю небольшой сервер, используя java.nio, но, пытаясь провести его стресс-тестирование, я получаю сообщения о том, что соединение сбрасывается на стороне сервера, или, более конкретно:

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

Я пытался сузить круг до самых простых циклов, но все равно не повезло. Я могу получить ошибку после сотни или около того подключений, или, может быть, сразу после 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() делает проблему исчезающей (но, в свою очередь, это ужасно медленно). Так что либо я не высвобождаю все ресурсы, которые я должен освободить, либо приложение просто требует паузы ..

Я теряю все свои лучшие годы на этом. Да, и кстати ... если я игнорирую запись в канал и просто закрываюсь после того, как принимаю соединение, проблема все еще не исчезает.

Ответы [ 2 ]

0 голосов
/ 05 августа 2015

С документы для SocketChannel # Запись (выделено мной):

Предпринята попытка записать до r байтов в канал, где r количество байтов, оставшихся в буфере, то есть src.remaining(), на данный момент этот метод вызывается.

[...]

Возвращает: Количество записанных байтов, возможно, ноль .

Вы должны проверить возвращаемое значение из вызова записи (чего вы не делаете в настоящее время) и выполнять последовательные вызовы записи до тех пор, пока весь буфер не будет отправлен. Примерно так, наверное:

ByteBuffer toWrite = ByteBuffer.wrap(response);
while (toWrite.remaining() > 0) {
    newChannel.write(toWrite);
}

Вы, очевидно, прерветесь, если не напишите все свои данные ответа, а затем просто закроете сокет.

0 голосов
/ 17 февраля 2011

Ну, я узнал об этом, поэтому я мог бы поделиться этим.

Моему приложению нужна пауза.Он просто шел слишком быстро и закрывал соединение до того, как клиент записал все свои данные запроса.Исправление будет состоять в том, чтобы продолжать чтение, пока не будет получен весь HTTP-запрос.О, урок усвоен.

...