Я получаю следующую ошибку при чтении из сокета. Я делаю readInt()
на этом InputStream
, и я получаю эту ошибку. Изучая документацию, можно предположить, что клиентская часть соединения закрыла соединение. В этом сценарии я являюсь сервером.
У меня есть доступ к файлам журнала клиента, и он не закрывает соединение, и на самом деле его файлы журнала предполагают, что я закрываю соединение. Кто-нибудь знает, почему это происходит? Что еще проверить? Возникает ли это, когда есть местные ресурсы, которые, возможно, достигают пороговых значений?
Замечу, что у меня есть такая строка:
socket.setSoTimeout(10000);
непосредственно перед readInt()
. Для этого есть причина (длинная история), но просто любопытно, есть ли обстоятельства, при которых это могло бы привести к указанной ошибке? У меня есть сервер, работающий в моей IDE, и я случайно оставил свою IDE застрявшей в точке останова, и затем я заметил, что те же самые ошибки начали появляться в моих собственных журналах в моей IDE.
В любом случае, просто упоминание об этом, надеюсь, не отвлекающий маневр. :-(
источник
Ответы:
Есть несколько возможных причин.
Другой конец намеренно сбросил соединение, что я здесь не буду описывать. Прикладное программное обеспечение делает это редко и, как правило, неправильно, но для коммерческого программного обеспечения это известно.
Чаще всего это вызвано записью в соединение, которое другой конец уже нормально закрыл. Другими словами, ошибка протокола приложения.
Это также может быть вызвано закрытием сокета, когда в приемном буфере сокета есть непрочитанные данные.
В Windows «программное обеспечение вызвало прерывание соединения», что не то же самое, что «сброс соединения», вызвано сетевыми проблемами при отправке с вашего конца. Об этом есть статья в базе знаний Microsoft.
источник
Сброс соединения означает просто получение TCP RST. Это происходит, когда ваш партнер получает данные, которые он не может обработать, и для этого могут быть разные причины.
Самый простой - это когда вы закрываете сокет, а затем записываете больше данных в выходной поток. Закрывая сокет, вы сказали своему партнеру, что вы закончили говорить, и он может забыть о вашем соединении. Когда вы все равно отправляете в этот поток больше данных, одноранговый узел отклоняет их с помощью RST, чтобы вы знали, что он не слушает.
В других случаях вмешивающийся межсетевой экран или даже сам удаленный хост могут «забыть» о вашем TCP-соединении. Это может произойти, если вы не отправляете никаких данных в течение длительного времени (2 часа - обычный тайм-аут) или из-за того, что одноранговый узел был перезагружен и потерял информацию об активных соединениях. Отправка данных по одному из этих несуществующих соединений также вызовет RST.
Обновление в ответ на дополнительную информацию:
Внимательно посмотрите на то, как вы работаете с
SocketTimeoutException
. Это исключение возникает, если превышен настроенный тайм-аут при блокировании операции сокета. Состояние самого сокета не изменяется при возникновении этого исключения, но если ваш обработчик исключений закрывает сокет, а затем пытается записать в него, вы будете в состоянии сброса соединения.setSoTimeout()
предназначен для того, чтобы дать вам чистый способ прерватьread()
операцию, которая в противном случае могла бы заблокироваться навсегда, без каких-либо грязных вещей, таких как закрытие сокета из другого потока.источник
Всякий раз, когда у меня возникают такие странные проблемы, я обычно сажусь с таким инструментом, как WireShark, и смотрю на необработанные данные, передаваемые туда и обратно. Вы можете быть удивлены, когда что-то отключается, и вы получаете уведомление только тогда, когда пытаетесь прочитать.
источник
Стыдно это говорить, но когда у меня возникла эта проблема, я просто по ошибке закрывал соединение, прежде чем прочитал все данные. В случаях, когда возвращались небольшие строки, это работало, но, вероятно, это было связано с тем, что весь ответ был буферизован, прежде чем я его закрыл.
В случаях, когда возвращалось большее количество текста, вызывалось исключение, поскольку возвращалось больше буфера.
Вы можете проверить эту оплошность. Помните, что открытие URL-адреса похоже на файл, обязательно закройте его (освободите соединение), как только он будет полностью прочитан.
источник
Вам следует очень внимательно изучить всю трассировку,
У меня есть приложение для серверного сокета, и я исправил
java.net.SocketException: Connection reset
случай.В моем случае это происходит при чтении из
Socket
объекта clientSocket, который по какой-то причине закрывает свое соединение. (Потеря сети, сбой брандмауэра или приложения или запланированное закрытие)На самом деле я повторно устанавливал соединение, когда у меня возникла ошибка при чтении из этого объекта Socket.
Интересно то, что
for my JAVA Socket
если клиент подключается к myServerSocket
и закрывает свое соединение без отправки чего-либо,is.read()
вызывает себя рекурсивно. Похоже, что из-за того, что вы находитесь в бесконечном цикле while для чтения из этого сокета, вы пытаетесь читать из закрытого соединения. Если вы используете что-то подобное ниже для операции чтения;Затем вы получаете stackTrace примерно так, как показано ниже.
Я просто закрыл ServerSocket и обновил свое соединение и ждал дальнейших входящих клиентских подключений.
Это восстанавливает мое соединение при потере неизвестного клиентского сокета
Я не мог найти другого способа, потому что, как вы видите на изображении ниже, вы не можете понять, потеряно соединение или нет, без a
try and catch
, потому что все кажется правильным. Я получил этот снимок, пока делалConnection reset
непрерывно.источник
У меня была такая же ошибка. Я нашел решение проблемы. Проблема заключалась в том, что клиентская программа завершала работу до того, как сервер прочитал потоки.
источник
У меня была эта проблема с системой SOA, написанной на Java. Я запускал и клиент, и сервер на разных физических машинах, и они долгое время работали нормально, затем эти неприятные сбросы подключения появились в журнале клиента, и в журнале сервера не было ничего странного. Перезапуск клиента и сервера не решил проблему. Наконец, мы обнаружили, что куча на стороне сервера была довольно заполнена, поэтому мы увеличили объем памяти, доступной для JVM: проблема решена! Обратите внимание, что в журнале не было OutOfMemoryError: памяти было мало, она не была исчерпана.
источник
Проверьте версию 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
источник
У меня также была эта проблема с программой Java, пытающейся отправить команду на сервер через SSH. Проблема заключалась в том, что машина выполняла код Java. У него не было разрешения на подключение к удаленному серверу. Метод write () работал нормально, но метод read () выдавал java.net.SocketException: сброс соединения. Я исправил эту проблему, добавив клиентский SSH-ключ к известным ключам удаленного сервера.
источник
По моему опыту, я часто сталкиваюсь со следующими ситуациями;
Если вы работаете в корпоративной компании, обратитесь в службу безопасности и сети. Поскольку в запросах к внешним службам может потребоваться предоставить разрешение для соответствующей конечной точки.
Другая проблема заключается в том, что срок действия сертификата SSL мог истечь на сервере, на котором работает ваше приложение.
источник