Java: устранение путаницы в том, что вызывает сброс соединения

Кажется, есть некоторая путаница, а также противоречащие заявления о различных ответах SO: Что вызывая мой java.net.SocketException: сброс подключения?. Здесь вы можете видеть, что в принятом ответе указано, что соединение было закрыто другой стороной. Но это неправда, закрытие соединения не вызывает сброса соединения. Это вызвано «основной ошибкой TCP / IP».

Я хочу знать, действительно ли SocketException: Connection reset означает помимо «неподтвержденной ошибки TCP / IP». Что на самом деле вызывает это? Насколько я сомневаюсь, это имеет какое-либо отношение к закрытию соединения (поскольку закрытие соединения не является флагом исключения, а чтение из закрытого соединения является, но это не «основная ошибка TCP / IP».

Моя гипотеза такова

Сброс соединения вызван отказом сервера подтвердить пакет ACK (полностью или просто неправильно в соответствии с TCP / IP). И что SocketTimeoutException генерируется только тогда, когда не генерируются данные для чтения (поскольку оно генерируется во время чтения по истечении определенного времени, а чтение ожидает данных, но не имеет отношения к пакетам ACK). Другими словами, read () выбрасывает SocketTimeoutException, если он не прочитал ни одного байта фактических данных (СЛОЙ ДАННЫХ) за отведенное время.


person Zombies    schedule 22.04.2010    source источник
comment
«Сброс соединения вызван отказом сервера подтвердить пакет ACK»: нет. Это вызвано закрытием соединения, в котором все еще есть непрочитанные данные; отправляя данные в соединение, которое одноранговый узел уже закрыл; или возиться с SO_LINGER перед закрытием.   -  person user207421    schedule 23.03.2021


Ответы (2)


Из источников openjdk6 видно, что «Сброс соединения» выдается, когда попытка чтения данных завершается неудачно с ошибкой ECONNRESET (Linux и Solaris) или WSAECONNRESET (Windows).

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

person Devon_C_Miller    schedule 22.04.2010
comment
В jdk/src/solaris/native/java/net/SocketInputStream.c сообщение сброса соединения может быть вызвано как EPIPE, так и ECONNRESET. - person hertzsprung; 05.03.2013
comment
Завершение работы не является необходимым и не вызывает этой ошибки, если оно не выполнено. Обычно это происходит, когда одноранговый узел закрывает соединение, не прочитав все ожидающие данные. - person user207421; 23.03.2021

По моему опыту, это происходит, когда клиент прерывает запрос (пользователь закрыл вкладку или щелкнул другую ссылку).

person Guillaume    schedule 22.04.2010
comment
Вы немного говорите в контексте веб-приложений. Вопрос, похоже, не в веб-приложениях. - person BalusC; 22.04.2010
comment
Я не уверен, в чем вопрос на самом деле, но связанный вопрос показал журнал ошибок Tomcat. Сообщение «сброс соединения» окончательно появляется, когда клиенты внезапно закрывают соединение, хотя, возможно, и в других ситуациях. - person Guillaume; 23.04.2010