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

java.net.SocketException: Connection reset

java.net.SocketException: сброс подключения

Я получаю следующую ошибку при попытке чтения из сокета. Я делаю readInt() над этим InputStream, и я получаю эту ошибку. При просмотре документации можно предположить, что клиентская часть соединения закрыла соединение. В этом сценарии я являюсь сервером.

У меня есть доступ к файлам журнала клиента, и он не закрывает соединение, а его файлы журнала предполагают, что я закрываю соединение. Итак, у кого-нибудь есть идея, почему это происходит? Что еще нужно проверить? Возникает ли это, когда есть локальные ресурсы, которые, возможно, достигают пороговых значений?


Я отмечаю, что у меня есть следующая строка:

socket.setSoTimeout(10000);

непосредственно перед readInt(). Для этого есть причина (долгая история), но просто любопытно, существуют ли обстоятельства, при которых это может привести к указанной ошибке? У меня запущен сервер в моей IDE, и так получилось, что моя IDE застряла на точке останова, а затем я заметил, что точно такие же ошибки начали появляться в моих собственных журналах в моей IDE.

В любом случае, просто упоминаю об этом, надеюсь, не отвлекающий маневр.

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

Существует несколько возможных причин.


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


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


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


  4. В Windows "прерывание соединения по программному обеспечению", что не то же самое, что "сброс подключения", вызвано сетевыми проблемами при отправке с вашей стороны. Об этом есть статья в базе знаний Microsoft.


Ответ 2

Сброс подключения просто означает, что был получен TCP RST. Это происходит, когда ваш одноранговый узел получает данные, которые он не может обработать, и на это могут быть различные причины.

Самый простой - это когда вы закрываете сокет, а затем записываете дополнительные данные в выходной поток. Закрывая сокет, вы сообщаете своему партнеру, что закончили общение, и он может забыть о вашем подключении. Когда вы все равно отправляете больше данных по этому потоку, одноранговый узел отклоняет их с помощью RST, чтобы сообщить вам, что он не прослушивает.

В других случаях подключенный брандмауэр или даже сам удаленный хост могут "забыть" о вашем TCP-соединении. Это может произойти, если вы долгое время не отправляете никаких данных (2 часа - обычный тайм-аут) или потому, что одноранговый узел был перезагружен и потерял информацию об активных соединениях. Отправка данных по одному из этих несуществующих подключений также вызовет RST.


Обновление в ответ на дополнительную информацию:

Внимательно посмотрите на вашу обработку SocketTimeoutException. Это исключение возникает, если превышен настроенный тайм-аут при блокировке операции с сокетами. Состояние самого сокета не изменяется при возникновении этого исключения, но если ваш обработчик исключений закроет сокет, а затем попытается выполнить запись в него, вы окажетесь в состоянии сброса соединения. setSoTimeout() предназначен для предоставления вам чистого способа прервать read() операцию, которая в противном случае могла бы быть заблокирована навсегда, без выполнения грязных действий, таких как закрытие сокета из другого потока.

Ответ 3

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

Ответ 4

Вам следует очень тщательно проверить полную трассировку,

У меня есть серверное приложение для сокетов, и я исправил java.net.SocketException: Connection reset случай.

В моем случае это происходит при чтении из clientSocket Socket объекта, соединение с которым по какой-либо причине закрыто. (Потеря сети, сбой брандмауэра или приложения или предполагаемое закрытие)

На самом деле я восстанавливал соединение, когда получил сообщение об ошибке при чтении из этого объекта сокета.

Socket clientSocket = ServerSocket.accept();
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
int readed = is.read(); // WHERE ERROR STARTS !!!

Интересно то, что for my JAVA Socket если клиент подключается к моему ServerSocket и закрывает свое соединение, ничего не отправляя, is.read() вызывается повторно.Кажется, что из-за бесконечного цикла while для чтения из этого сокета вы пытаетесь читать из закрытого соединения.
Если вы используете что-то вроде приведенного ниже для операции чтения;

while(true)
{
Receive();
}

Затем вы получаете stackTrace примерно так, как показано ниже, снова и снова

java.net.SocketException: Socket is closed
at java.net.ServerSocket.accept(ServerSocket.java:494)

Что я сделал, так это просто закрыл ServerSocket, обновил свое соединение и стал ждать дальнейших входящих клиентских подключений

String Receive() throws Exception
{
try {
int readed = is.read();
....
}catch(Exception e)
{
tryReConnect();
logit(); //etc
}


//...
}

Это восстанавливает мое соединение при потерях неизвестного клиентского сокета

private void tryReConnect()
{
try
{
ServerSocket.close();
//empty my old lost connection and let it get by garbage col. immediately
clientSocket=null;
System.gc();
//Wait a new client Socket connection and address this to my local variable
clientSocket= ServerSocket.accept(); // Waiting for another Connection
System.out.println("Connection established...");
}catch (Exception e) {
String message="ReConnect not successful "+e.getMessage();
logit();//etc...
}
}

Я не смог найти другого способа, потому что, как вы видите на изображении ниже, вы не можете понять, потеряно соединение или нет без try and catch , потому что все кажется правильным. Я получил этот снимок, пока получал Connection reset непрерывно.

введите описание изображения здесь

java