Я получаю следующую ошибку при попытке чтения из сокета. Я выполняю readInt()
на этом InputStream
, и получаю эту ошибку. Изучение документации говорит о том, что клиентская часть соединения закрыла соединение. В этом сценарии я являюсь сервером.
У меня есть доступ к лог-файлам клиента, и он не закрывает соединение, и на самом деле его лог-файлы показывают, что я закрываю соединение. Есть ли у кого-нибудь идеи, почему это происходит? Что еще нужно проверить? Возникает ли это, когда есть локальные ресурсы, которые, возможно, достигают пороговых значений?
Я отмечаю, что у меня есть следующая строка:
socket.setSoTimeout(10000);
непосредственно перед readInt()
. Для этого есть причина (долгая история), но просто любопытно, есть ли обстоятельства, при которых это может привести к указанной ошибке? У меня сервер запущен в IDE, и я случайно оставил IDE на точке останова, а затем заметил, что точно такие же ошибки начали появляться в моих собственных логах в IDE.
В любом случае, просто упомянул об этом, надеюсь, это не красная селедка. :-(
Существует несколько возможных причин.
Другой конец намеренно сбросил соединение способом, который я не буду здесь описывать. Прикладное программное обеспечение делает это редко и, как правило, неправильно, но для коммерческого программного обеспечения это не редкость.
Чаще всего это вызвано записью в соединение, которое на другом конце уже нормально закрыто. Другими словами, ошибка протокола приложения.
Она также может быть вызвана закрытием сокета при наличии непрочитанных данных в буфере приема сокета.
В Windows 'программно вызванное прерывание соединения', что не то же самое, что 'сброс соединения', вызвано сетевыми проблемами при отправке с вашей стороны. Об этом есть статья в базе знаний Microsoft.
Сброс соединения означает, что был получен TCP RST. Это происходит, когда ваш аналог получает данные, которые он не может обработать, и для этого могут быть различные причины.
Самая простая - это когда вы закрываете сокет, а затем записываете больше данных в выходной поток. Закрывая сокет, вы сообщаете своему аналогу, что вы закончили разговор, и он может забыть о вашем соединении. Когда вы все равно посылаете больше данных в этот поток, аналог отклоняет их с помощью RST, чтобы сообщить вам, что он не слушает.
В других случаях межсетевой экран или даже сам удаленный узел может "забыть" о вашем TCP-соединении. Это может произойти, если вы долгое время не отправляете данные (2 часа - обычный тайм-аут), или если удаленный хост был перезагружен и потерял информацию об активных соединениях. Отправка данных по одному из таких неработающих соединений также вызовет RST.
Обновление в ответ на дополнительную информацию:
Внимательно изучите свою обработку исключения SocketTimeoutException
. Это исключение возникает, если превышен настроенный тайм-аут при блокировке операции с сокетом. Состояние самого сокета не изменяется при возникновении этого исключения, но если ваш обработчик исключения закроет сокет, а затем попытается записать в него данные, вы окажетесь в состоянии сброса соединения. Функция setSoTimeout()
предназначена для того, чтобы дать вам чистый способ выйти из операции read()
, которая в противном случае могла бы заблокироваться навсегда, не делая грязных вещей, таких как закрытие сокета из другого потока.
Когда у меня возникали подобные проблемы, я обычно садился с таким инструментом, как WireShark, и просматривал необработанные данные, передаваемые туда и обратно. Вы можете быть удивлены тем, где все разъединяется, а вы получаете уведомление только при попытке чтения.
Вы должны очень внимательно осмотреть полную трассировку,
Я'вэ приложение сокет-сервера, исправлено Ява.чистая.Исключения socketexception: случае сброс соединения
.
В моем случае это происходит при чтении из объекта clientSocket гнездо
, которая закрыла свои связи из-за некоторых причин. (Сеть потерял,брандмауэр или сбоя приложения или предполагается закрыть)
На самом деле я был повторного установления соединения, когда я получил сообщение об ошибке при чтении из этого объекта сокета.
Socket clientSocket = ServerSocket.accept();
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
int readed = is.read(); // WHERE ERROR STARTS !!!
Интересно, что для моего сокета Java, если клиент подключается к моему ServerSocket и закрыть соединение без отправки является.читать()` вызывает сама себя рекурсивно.Кажется, что находясь в бесконечный цикл while для чтения из этого сокета попытке чтения из закрытого соединения. Если вы используете что-то вроде ниже для операции чтения;
while(true)
{
Receive();
}
Тогда вы получите что-то вроде трассировки стека ниже и на
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
}
//...
}
Это reestablises свою связь по неизвестным клиентского сокета потери
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...
}
}
Я не мог'т искать другой путь, поскольку как видно из изображения ниже вы можете'т понять, есть ли соединение потеряно или не поймать
,потому что все вроде правильно . Я получил этот снимок в то время как я получаю подключение перезагрузки
постоянно.
Неловко говорить, но когда у меня была эта проблема, это было просто ошибкой, что я был закрытия подключения, прежде чем я прочитал все данные. В случаях с небольшим строк вернулся, он работал, но это было, вероятно, из-за весь ответ в буфер, прежде чем я закрыл его.
В случаях длительного объемы текста возвращается, исключение было выдано, так как больше буфера вернется.
Вы можете проверить эту оплошность. Помните, открытие URL-адреса, как файл, обязательно закройте его (выпустите связи) после того, как он уже прочитан.
Я имел эту проблему с SOA-системы, написанные на Java. Я бежал и клиент и сервер на разных физических машинах, и они прекрасно работали в течение длительного времени, то эти неприятные сбрасывает соединение появилось в журнале клиента и там'т ничего странного в журнале работы сервера. Перезапуск клиента и сервера, это'т решить проблему. Наконец, мы обнаружили, что куча на стороне сервера был довольно полон, поэтому мы увеличили объем памяти, доступной для JVM: проблема решена! Обратите внимание, что не было никакого исключение OutOfMemoryError в журнале: памяти просто мало, не исчерпывается.
Я также имел эту проблему с Java-программа пытается отправить команду на сервер через SSH. Проблема была с машиной для выполнения Java-кода. Это не'т иметь разрешение на подключение к удаленному серверу. Метод write() был делаешь хорошо, но read() метод, набросив на Java.чистая.Исключения socketexception: сброс подключения. Я исправил эту проблему с помощью добавления клиентского ключа SSH к удаленному серверу известных ключей.
Проверьте ваш сервер'версии Java с. Случилось со мной, потому что мой сервер WebLogic 10.3.6 был на JDK 1.7.0_75, который был на протоколе TLSv1. Остальные конечной точки я пытался потреблять закрывает все, что ниже в протоколе TLSv1.2.
По умолчанию сервер WebLogic пытался договориться сильнейший общий протокол. Подробности здесь: https://stackoverflow.com/questions/34283829/issues-with-setting-https-protocols-system-property-for-https-connections.
Я добавил подробный протокол SSL лесозаготовки чтобы определить поддержку протокола TLS. Это указано в протоколе TLSv1, используется для квитирования.<БР/>
-Djavax.чистая.отладка=SSL-шифрование:квитирование:подробно:keymanager:диспетчер trustmanager -Джава.безопасности.отладка=доступ:стек
Я решил эту проблему, выдвигая эту особенность нашей JDK8-совместимый продукт, по умолчанию JDK8 в протоколе TLSv1.2. Для тех, кто ограничен в JDK7, я также успешно протестировали решение для Java 7, обновление в протоколе TLSv1.2. Я использовал этот ответ: https://stackoverflow.com/questions/39157422/how-to-enable-tls-1-2-in-java-7