Java.net.SocketException: Соединение reset

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

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


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

socket.setSoTimeout(10000);

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

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

Ответ 1

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

  • На другом конце умышленно reset соединение, таким образом, что я не буду документировать здесь. Редко и, как правило, неверно, для прикладного программного обеспечения это делать, но это не известно для коммерческого программного обеспечения.

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

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

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

Ответ 2

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

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

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


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

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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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

У меня есть приложение для подключения к серверу и исправлено событие 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.

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

Ответ 9

Проверьте версию вашего сервера Java. Произошло со мной, потому что мой Weblogic 10.3.6 был на JDK 1.7.0_75, который был на TLSv1. Остальной конечной точкой, которую я пытался использовать, было отключение чего-либо ниже TLSv1.2.

По умолчанию Weblogic пытался согласовать самый сильный общий протокол. Подробнее см. здесь: Проблемы с настройкой системного свойства https.protocols для подключений HTTPS.

Я добавил подробное протоколирование SSL, чтобы определить поддерживаемый TLS. Это указывало на то, что TLSv1 использовался для рукопожатия.
-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack

Я решил эту проблему, добавив эту функцию в наш JDK8-совместимый продукт, по умолчанию JDK8 - TLSv1.2. Для тех, кто ограничен JDK7, я также успешно протестировал обходной путь для Java 7 путем обновления до TLSv1.2. Я использовал этот ответ: Как включить TLS 1.2 в Java 7