2013-11-25 5 views
0

Я застрял в головоломке здесь ...Java-клиент SSLSocket: как узнать, закрыл ли удаленный конец соединение?

Мой клиент SSLSocket подключается к серверу (а не к Java) и успешно считывает и записывает двоичные данные, как ожидалось. Затем, в какой-то момент времени, сервер отключает соединение клиента. Тем не менее, клиент все еще может звонить startHandshake(), не выдавая исключение, и я не вижу никаких признаков того, что соединение нарушено, за исключением того, что getLocalSocketAddress() возвращает IP всех 0.

Вот что код выглядит следующим образом:

SSLSocket socket = (SSLSocket)socketFactory.createSocket(host, port); 
socket.setTcpNoDelay(true); 
socket.setKeepAlive(true); 

/* Socket happily sends/receives data */ 
socket.getOutputStream().write(myData); 
socket.getOutputStream().flush(); 
socket.getInputStream().read(myBuffer); 
// do something with myBuffer 

Thread.sleep(20 * 1000); // During this wait period, server disconnects the client 

socket.getLocalSocketAddress(); // returns host:port as expected 

socket.startHandshake(); // doing another read/write will also produce the same result 

socket.getLocalSocketAddress(); // returns an IP of all zeroes: /0:0:0:0:0:0:1129:6a1f%0:51447 
socket.isClosed(); // somehow, returns false! 
socket.isConnected(); // somehow, returns true! 

socket.getOutputStream.write(myOtherData); // throws a SocketException: Broken pipe. 

В принципе, я думаю, мой вопрос, есть ли какой-то способ определения того, будет ли сервер нарушил связь, кроме проверки, если getLocalSocketAddress() имеет IP все 0 ' ?

ответ

2
  • Socket.getLocalAddress() возвращает все нули, если вы закрыли сокет или не связали его или не связали.
  • Socket.isClosed() сообщает, закрыты ли вы розетку.
  • Socket.isConnected() Сообщает вам, подключен ли вы к розетке.

Чтобы проверить, является ли равный закрыл соединение:

  1. read() возвращает -1
  2. readLine() возвращает Null
  3. readObject(), readInt(), readXXX() для любого другого XXX, бросить EOFException.
+0

Удивительный! read() делает именно то, что я хочу. Теперь, следующий вопрос ... как получилось, когда я начинаюHandshake выше, это не исключение? Не следует ли, чтобы базовый уровень SSL или TCP обнаружил, что сервер закрыл соединение? Я также могу написать данные без его исключения. Спасибо! – osman

+1

(a) Участник не может закрыть соединение, не выполнив сначала рукопожатие, поэтому квитирование вашей стороны всегда будет успешным; (b) из-за буферизации вы, как правило, можете писать хотя бы один раз, прежде чем возникнуть прерывистое исключение трубы. – EJP

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