it-swarm-ru.tech

java.net.SocketException: сброс соединения

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

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


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

socket.setSoTimeout(10000);

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

Во всяком случае, просто упоминая об этом, надеюсь, не красная сельдь. :-(

101
Darryl

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

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

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

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

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

100
user207421

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

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

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


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

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

41
erickson

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

13
GEOCHET

Мне стыдно это говорить, но когда у меня возникла эта проблема, было просто ошибкой, что я закрывал соединение до того, как прочитал все данные. В случаях, когда возвращались небольшие строки, это работало, но это, вероятно, было связано с буферизацией всего ответа, прежде чем я его закрыл.

В тех случаях, когда возвращалось большее количество текста, генерировалось исключение, так как возвращалось больше буфера.

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

8
Scott S

Вы должны тщательно проверить полный след,

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

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

На самом деле я восстанавливал соединение, когда у меня возникла ошибка при чтении с этого объекта 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(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.

enter image description here

7
Davut Gürbüz

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

5
kml_ckr

У меня была эта проблема с системой SOA, написанной на Java. Я работал и на клиенте, и на сервере на разных физических машинах, и они долгое время работали нормально, затем эти неприятные сбросы подключения появились в журнале клиента, и в журнале сервера не было ничего странного. Перезапуск клиента и сервера не решил проблему. Наконец, мы обнаружили, что куча на стороне сервера была довольно полной, поэтому мы увеличили объем памяти, доступной для JVM: проблема решена! Обратите внимание, что в журнале не было OutOfMemoryError: памяти было недостаточно, не было исчерпано.

4
Pino

У меня также была эта проблема с программой Java, пытающейся отправить команду на сервер через SSH. Проблема была в том, что на компьютере выполнялся код Java. У него не было разрешения на подключение к удаленному серверу. Метод write () работал нормально, но метод read () вызывал исключение Java.net.SocketException: сброс соединения. Я исправил эту проблему, добавив ключ SSH клиента к известным ключам удаленного сервера.

1
pmartin8