Официальные причины для "программного обеспечения вызвало прерывание соединения: ошибка записи сокета" - PullRequest
144 голосов
/ 24 января 2010

Учитывая этот фрагмент трассировки стека

Причина: java.net.SocketException: Программное обеспечение вызвало прерывание соединения: ошибка записи в сокет
при java.net.SocketOutputStream.socketWrite0 (Native Метод)

Я пытался ответить на следующие вопросы:

  1. Какой код выдает это исключение? (JVM? / Tomcat? / Мой код?)
  2. Что вызывает это исключение?

Относительно № 1:

Источник JVM от Sun не содержит этого точного сообщения, но я думаю, что текст Программное обеспечение вызвало прерывание соединения: ошибка записи в сокет из собственной реализации SocketOutputStream:

private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
                 int len) throws IOException;

Относительно # 2

Я предполагаю, что это вызвано тем, что клиент разорвал соединение, до получения полного ответа (например, отправил запрос, но до получения полного ответа он был закрыт / прерван / отключен)

Вопросы:

  1. Верны ли вышеизложенные предположения (# 1 и # 2)?
  2. Можно ли это дифференцировать от ситуации: «не удалось записать клиенту из-за сетевой ошибки на стороне сервера »? или это будет отображать то же сообщение об ошибке?
  3. И самое важное: Есть ли официальный документ (например, от Sun), подтверждающий вышесказанное?

Мне нужно иметь доказательство того, что эта трассировка стека является "ошибкой" клиента сокета, и сервер ничего не мог бы сделать, чтобы избежать этого. (кроме перехвата исключения или использования не JVM SocketOutputStream, не входящего в Sun, хотя и то, и другое не исключает факт, что клиент завершил работу)

Ответы [ 13 ]

51 голосов
/ 13 октября 2011

Эта ошибка может возникать, когда локальная сетевая система прерывает соединение, например, когда WinSock закрывает установленное соединение после сбоя повторной передачи данных (получатель никогда не подтверждает отправленные данные на сокете потока данных).

См. эту статью MSDN . См. Также Некоторая информация о 'программном сбое соединения по причине' .

8 голосов
/ 25 августа 2016

java.net.SocketException генерируется, когда возникает ошибка при создании или доступе к сокету (например, TCP ). Обычно это может быть вызвано тем, что сервер разорвал соединение (без надлежащего закрытия), поэтому перед получением полного ответа. В большинстве случаев это может быть вызвано либо проблемой тайм-аута (например, ответ занимает слишком много времени, либо сервер перегружен запросами), либо клиент отправил SYN, но не получил ACK (подтверждение завершения соединения) , При возникновении проблем с тайм-аутом можно рассмотреть возможность увеличения значения тайм-аута.

Исключение Socket обычно поставляется с указанным подробным сообщением о проблеме.

Пример подробных сообщений:

  • Программное обеспечение вызвало прерывание соединения: сбой recv.

    Ошибка указывает на попытку отправки сообщения, и соединение было прервано вашим сервером. Если это произошло при подключении к базе данных, это может быть связано с использованием несовместимого JDBC-драйвера Connector / J .

    Возможное решение: убедитесь, что в вашей CLASSPATH имеются правильные библиотеки / драйверы.

  • Программное обеспечение вызвало прерывание соединения: connect.

    Это может произойти, когда есть проблема с подключением к пульту. Например, из-за того, что средство проверки на вирусы отклоняет запросы удаленной почты .

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

  • Программное обеспечение вызвало прерывание соединения: ошибка записи в сокет.

    Возможное решение: убедитесь, что вы записываете правильную длину байтов в поток. Поэтому дважды проверьте, что вы отправляете. Смотрите эту тему .

  • Сброс соединения по пиру: ошибка записи сокета / Соединение прервано по пиру: ошибка записи сокета

    Приложение не проверяет, истекло ли время ожидания активности на стороне сервера.

    Возможное решение: убедитесь, что HttpClient не равен NULL, перед чтением из соединения. E13222_01

  • Сброс соединения по пиру.

    Соединение было прервано узлом (сервером).

  • Сброс соединения.

    Соединение было прервано клиентом или закрыто серверным концом соединения из-за запроса с запросом.

    См .: В чем причина моего java.net.SocketException: сброс подключения?

8 голосов
/ 31 января 2013

Я видел это чаще всего, когда корпоративный брандмауэр на рабочей станции / ноутбуке мешает, он разрывает соединение.

например. У меня есть процесс сервера и процесс клиента на одной машине. Сервер прослушивает все интерфейсы (0.0.0.0), а клиент пытается подключиться к общедоступному / домашнему интерфейсу (обратите внимание, что интерфейс обратной связи 127.0.0.1).

Если устройство отключено от сети (например, отключен Wi-Fi), соединение будет установлено. Если аппарат подключен к корпоративной сети (напрямую или через vpn), то соединение установлено.

Однако, если устройство подключено к общедоступной сети Wi-Fi (или домашней сети), брандмауэр отключает соединение. В этой ситуации подключение клиента к интерфейсу обратной связи работает нормально, только не к интерфейсу home / public.

Надеюсь, это поможет.

4 голосов
/ 24 января 2010

Чтобы доказать, какой компонент выходит из строя, я бы отслеживал связь TCP / IP с помощью wireshark и смотрел, кто на самом деле закрывает порт, также могут иметь значение таймауты.

2 голосов
/ 25 ноября 2014

Для тех, кто использует простые программы Client Server и получает эту ошибку, это проблема закрытых (или закрытых до раннего) потоков ввода или вывода.

2 голосов
/ 24 января 2010

Вы проверяли исходный код Tomcat и исходный код JVM? Это может дать вам больше помощи.

Я думаю, что у тебя хорошее мышление. Я ожидаю ConnectException в сценарии, который вы не можете подключить. Вышеприведенное выглядит очень похоже на то, что оно управляется клиентом.

1 голос
/ 28 июня 2016

Я столкнулся с той же проблемой.
Обычно ошибка такого рода возникает из-за того, что клиент закрыл соединение и сервер все еще пытается выполнить запись на этом клиенте.
Поэтому убедитесь, что у вашего клиента открыто соединение, пока сервер не завершит свой выходной поток.
И еще одна вещь, не забывайте закрыть входной и выходной поток.

Надеюсь, это поможет.
И если проблема еще не решена, кратко опишите вашу проблему здесь.

0 голосов
/ 13 октября 2017

В ситуации, описанной ниже, клиентская сторона выдаст такое исключение:

Сервер запрашивает аутентификацию сертификата клиента, но клиент предоставляет сертификат, который при расширенном использовании ключа не поддерживает аутентификацию клиента, поэтому сервер не принимает сертификат клиента, а затем закрывает соединение.

0 голосов
/ 12 октября 2017

ssl клиентская сторона выдаст такое исключение в ситуации ниже (я проверял),:

серверу запрашивается проверка подлинности сертификата клиента, но клиент предоставляет сертификат, который не поддерживается клиентом для расширенного использования ключа.

0 голосов
/ 23 февраля 2017

Закрытое соединение в другом клиенте

В моем случае ошибка была:

java.net.SocketException: Software caused connection abort: recv failed

Он был получен в Eclipse при отладке Java-приложения, обращающегося к базе данных H2. Источником ошибки было то, что я первоначально открыл базу данных с помощью SQuirreL, чтобы проверить целостность вручную. Я использовал флаг, чтобы разрешить несколько подключений к одной и той же БД (т.е. AUTO_SERVER=TRUE), поэтому не было проблем с подключением к БД из Java.

Ошибка появилась, когда через некоторое время - это долгий процесс Java - я решил закрыть SQuirreL для освобождения ресурсов. Похоже, что SQuirreL был «владельцем» экземпляра сервера БД и что он был закрыт с помощью соединения SQuirreL.

Перезапуск приложения Java не привел к ошибке снова.

конфиг

  • Windows 7
  • Затмение Кеплера
  • SQuirreL 3.6
  • org.h2.Driver ver 1.4.192
...