Я получаю следующую ошибку, пытающуюся прочитать из сокета. Я делаю 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