SSL socket blocks on close

I am using an ssl socket connection with a long lifespan. I'm using it to receive event information from a server.

My problem occurs when the client os's underlying network connection drops out and comes back. When it re-appears the application re-establishes the event socket connection, by first calling disconnect shown here:

protectedfinalvoid disconnect()throws IOException{

try{

output.flush();

}finally{

try{

output.close();

}finally{

output =null;

try{

input.close();

}finally{

input =null;

try{

socket.close();

}finally{

socket =null;

}

}

}

}

}

I'm noticing that when using SSL this code blocks on either input.close(); (the socket's input stream) or socket.close(); (if input.close() has been commented out).

"MyEventThread" daemon prio=10 tid=0x0818c400 nid=0x6c66 waitingfor monitor entry [0xacaba000..0xacabaf30]

java.lang.Thread.State: BLOCKED (on object monitor)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:714)

- waiting to lock <0xae8e4738> (a java.lang.Object)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.waitForClose(SSLSocketImpl.java:1368)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.closeInternal(SSLSocketImpl.java:1324)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.close(SSLSocketImpl.java:1218)

I'm not sure as to the correct approach here; if i need to make the application-level code aware of the specific case where the network is dropped and write an implementation that doesn't bother trying to close and just nullify everything or if a better option is to set socket-level options to try and adjust the ssl-socket's implementation behaviour.

Thanks.

[2874 byte] By [raykroekera] at [2007-11-27 7:42:46]
# 1

Well you can get rid of 3/4 of that code. When you close an output stream it is auto-flushed, and when you close the output stream of a Socket, the input stream and the Socket are automatically closed. I don't know why the block is happening but as you don't need to call the method that causes it, the problem will disappear.

ejpa at 2007-7-12 19:23:40 > top of Java-index,Core,Core APIs...
# 2
Not so. As stated in the op; I do need to close the socket which will close the input stream which will block.
raykroekera at 2007-7-12 19:23:40 > top of Java-index,Core,Core APIs...
# 3
Not so. See reply #1. All you need is output.close(). The flush() and all the other closes can be removed.
ejpa at 2007-7-12 19:23:40 > top of Java-index,Core,Core APIs...
# 4
Totally agree with ejp, you don't need them all...
JavaPaladina at 2007-7-12 19:23:40 > top of Java-index,Core,Core APIs...
# 5

> I don't know why the block is happening ....

Doesn't a disconnect attempt to send info to the other end?

The OP said the other end dropped which I suspect might mean an abrupt disconnect rather than a nice one. So if a disconnect attempts to close nicely then wouldn't there be some timeouts?

jschella at 2007-7-12 19:23:40 > top of Java-index,Core,Core APIs...
# 6

What I think is happening here is this:

(a) the monitor-block shows that this disconnect() method is being invoked asynchronously, i.e by a thread which is somehow monitoring the connection, probably a timer thread started for each read.

(b) asynchronous close isn't specified to work for Sockets and therefore SSLSockets.

(c) I suspect that output.close() is probably throwing an Exception of some kind, which we haven't seen yet because we're blocked in the 'finally' block.

Just as for all the redundant closes, this is really doing it the hard way. The entire thing can be reduced to this:

socket.setSoTimeout(timeout);// in ms

try

{

int count = input.read(buffer);

// etc, whatever the application does ...

}

catch (SocketTimeoutException exc)

{

// read timeout - close the socket

try

{

output.close();

}

catch (IOException exc)

{

// ...

}

// initiate reconnection or whatever you want to do here

}

All in a single thread. No finally blocks, no flushing, no triple closing, no monitor blocking.

ejpa at 2007-7-12 19:23:40 > top of Java-index,Core,Core APIs...