开发者

SocketChannel: java.io.IOException: An existing connection was forcibly closed by the remote host

开发者 https://www.devze.com 2023-02-23 21:44 出处:网络
I\'m using a SocketChannel with a network socket, and have to handle the expected exception of the other end of the socket closing the channel unexpectedly.

I'm using a SocketChannel with a network socket, and have to handle the expected exception of the other end of the socket closing the channel unexpectedly.

The problem is, I get this IOException:

java.io.IOException: An existing connection was forcibly closed by the remote host
    at sun.ni开发者_C百科o.ch.SocketDispatcher.read0(Native Method)
    at sun.nio.ch.SocketDispatcher.read(Unknown Source)
    at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
    at sun.nio.ch.IOUtil.read(Unknown Source)
    at sun.nio.ch.SocketChannelImpl.read(Unknown Source)
    ...

I need to distinguish between this exception, which is expected to happen, and unexpected exceptions, so that I can log/print the unexpected ones and handle this one. But it's just an ordinary IOException with a different text message, and although I always check SocketChannel.isOpen() and SocketChannel.isConnected(), they seem to return true in this case even though the other end of the socket has been closed.

What can/should I do?


the isOpen() and isConnected() should be more accurately called hasBeenOpenned() and hasBeenConnected(). Once they are true, they do not return to false.

You may have to do a e.getMessage().contains("closed by the remote host"). Unfortunately, this is likely to be a platform dependant.

Instead I suggest you allow the protocol to send a "Closed" message of some kind and treat any exception without this first as unexpected.


This could be a bit ugly... You could play catch with it. Double try the code, catching the first exception and determining the message. If it's what you expect, ignore it, or do what you were going to do before. If it's not what you expected, go ahead and throw it to the higher try.

Now that I think about it, you could do this in a single try if you wanted to, just by looking at the message.

That being said, I think you should re-evaluate the idea of relying on this exception for flow of control of your program. Are you sure you should have a design that says "I'm wanting for this exception to happen"?

try {
    try {
       // your code
    } catch(IOException innerIOE) {
        if(innerIOE.getMessage().begins("An existing connection was forcibly closed")) {
            log.info("Exception expected, yay.");
        }
        else {
            throw innerIOE;
        }
    } // end inner catch
} catch(IOException outerIOE) {
    // error handling code here, your "An existing connection was forcibly closed"
    // shouldn't make it out here
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号