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

21,511

Solution 1

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.

Solution 2

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
}
Share:
21,511
Jason S
Author by

Jason S

Updated on October 30, 2020

Comments

  • Jason S
    Jason S over 3 years

    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.nio.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?

  • Jason S
    Jason S about 13 years
    yeah, I thought of parsing the message string -- it's ugly and I shouldn't have to do it, but it sounds like I don't have much else of a choice.
  • corsiKa
    corsiKa about 13 years
    Yeah I have to admit - I don't like this code at all. I try to operate by the mentality of "If an exception happens, there's a bug." I understand your case, though. Sometimes we just don't have the time/funding/politics to make things the way we want them. :-(
  • Jason S
    Jason S about 13 years
    I dunno why Sun didn't throw a ClosedChannelException instead.
  • Jason S
    Jason S about 13 years
    If I have to do it, I'll use your method, otherwise Peter has a point that it's preferable to send some kind of Closed message; I'll find a way. argh.
  • corsiKa
    corsiKa about 13 years
    I agree, making it being closed as part of the protocol is the way to go.
  • user207421
    user207421 about 13 years
    @Jason S: because ClosedChannelException means you have closed the channel. In the OP's case the channel isn't closed, the connection is closed.
  • Jason S
    Jason S about 13 years
    @EJP: (OP = me) -- well, then they should have defined a ConnectionClosedException or whatever.
  • corsiKa
    corsiKa about 13 years
    @Jason I agree. "IOException" is hardly descriptive. "Something went wrong with... something related to IO?" Was it file IO? Network IO? Old McDonald's farm EIE-IO library 2.0? Parsing the message is hardly a step up from the 4GLs of the 80s where you passed strings everywhere.
  • user207421
    user207421 about 13 years
    @Jason S: I agree too. I would have liked to see separate exceptions for all the ICMP errors.