aspose file tools*
The moose likes Java in General and the fly likes Java NIO socket communication: why can I still send data after the server closed the connection? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Java NIO socket communication: why can I still send data after the server closed the connection?" Watch "Java NIO socket communication: why can I still send data after the server closed the connection?" New topic
Author

Java NIO socket communication: why can I still send data after the server closed the connection?

Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14266
    
  21

I'm using the Java NIO API for socket communication (in blocking mode).

I noticed that when the remote host closes the connection, my client doesn't notice it - the client can still send data and doesn't get an exception, as if the data has been sent successfully. Have a look at the code below, which does the following: Start a very simple server, which accepts a connection and closes it after a short delay of 200ms. The client opens a connection, which the server accepts. Before sending data, the client waits one second, so that the server has closed the connection in the meantime. Then the client sends some data.

I would expect that an exception would happen in the client when trying to send the data, because the server has already closed the connection. However, this doesn't happen. Why not, and how can I detect if the connection is still open and can be used to send data? Calling channel.isConnected() doesn't work - it will return true even after the server has already closed the connection.

Output:

Client connected
Server accepted client connection
Server closed connection
Client sent 4 bytes
Client closed connection


Java Beginners FAQ - JavaRanch SCJP FAQ - The Java Tutorial - Java SE 8 API documentation
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14266
    
  21

I've found out myself why this happens. It has to do with how TCP/IP works.

TCP/IP is a connection-oriented protocol: you make a connection, then you can send and receive data, and at the end you close the connection. However, TCP is built on top of IP, which is a packet-oriented protocol. Some of this shows through the TCP protocol (it's a leaky abstraction - you're not supposed to be bothered with how TCP is implemented under the covers, but inevitably you have to deal with some of the implementation details anyway).

So, when the remote system closes the connection, the client might not notice it immediately, and it seems like you can still send data to the remote system. It will take a while before the client notices that no acknowledgements are received anymore.

One way to solve this is to define a disconnect message at the application-level protocol; in other words, the remote host should send the client a "I'm going to close the connection now!" message before really closing it.
James Kirk
Greenhorn

Joined: Dec 12, 2011
Posts: 7
Hi there,
I am digging out a rather old post, but it perfectly describes my question. My problem with the above setup is: The sending side only seems to recognize the dropped connection, if I send more data than I actually intend to (probably one has to send more than fits in the sockets send buffer). So my question is: can I safely detect if a connection has been dropped without an extra acknowledge mechanism?

Many TIA,
-- JK
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39393
    
  28
Don’t know myself, but welcome to the Ranch
James Kirk
Greenhorn

Joined: Dec 12, 2011
Posts: 7
Campbell Ritchie wrote:Don’t know myself, but welcome to the Ranch


Thanks a lot!

I have been searching for a good Java forum quite a while. Now I finally found one (-:
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Java NIO socket communication: why can I still send data after the server closed the connection?