2008-09-15 8 views
80

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

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


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

socket.setSoTimeout(10000); 

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

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

+0

У вас есть стек следы с обеих сторон? Можете ли вы описать сетевую архитектуру немного больше? (По дикому интернету? На той же машине? Где-то между ними?) Случается ли это все время? Или с перерывами? – 2008-09-15 13:45:39

ответ

8

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

31

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

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

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


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

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

+0

Неправильно в нескольких отношениях. Сбор мусора и выходы процесса как следят за закрытием, так и не сбрасываются, но закрытие, за которым следует запись одноранговым узлом, может вызвать сброс, а не EOS. SocketTimeoutExceptions создаются только в том случае, если читатель установил тайм-аут чтения. – EJP 2012-09-30 00:21:14

+0

И это не всегда означает получение RST. Это также может означать, что одна из них была создана этой стороной. – EJP 2017-04-14 17:35:03

+3

EJP еще соленый через 5 лет? – Daedric 2017-06-19 19:17:09

81

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

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

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

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

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

3

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

5

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

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

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

1

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

2

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

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() называет себя recursively.It кажется из-за того, чтобы быть в бесконечном в то время как петля для чтения из этого сокета вы пытаетесь прочитать из закрытого соединения. Если вы используете что-то вроде ниже для операции чтения;

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

 Смежные вопросы

  • Нет связанных вопросов^_^