Вопрос-ответ

Official reasons for "Software caused connection abort: socket write error"

Официальные причины "Прерывания соединения по программному обеспечению: ошибка записи в сокет"

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


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


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


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

  2. Что вызывает создание этого исключения?

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

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

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

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

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

Вопросы:


  1. Верны ли приведенные выше предположения (# 1 и # 2)?

  2. Можно ли отличить это от ситуации: "не удалось выполнить запись клиенту из-за сетевой ошибки на стороне сервера"? или это выдаст то же сообщение об ошибке?

  3. И самое важное: существует ли официальный документ (например, от Sun), подтверждающий вышеизложенное?

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

Переведено автоматически
Ответ 1

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


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

Ответ 2

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

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

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



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



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


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



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



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


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



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



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



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



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


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



  • Сброс соединения одноранговым узлом.



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



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



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


    Смотрите: Что вызывает исключение java.net.SocketException: сброс соединения?


Ответ 3

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

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

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

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

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

Ответ 4

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

java exception tomcat