Forums Register Login

Can writting to the socket wait infinitely

+Pie Number of slices to send: Send
If while writing to the socket's output stream, the peer closes the connection (or because of some reason the connectivity is loosed), will my program wait infinitely or will it timeout after certain amount of time.

I searched a lot, but unable to find the answer.
+Pie Number of slices to send: Send
It depends on what API you are using to access the remote resource, but I have found most when writing will throw some sort of Exception if the connection is dropped. However, it is important that you configure a timeout value when establishing a connection so that you don't ever wait indefinitely with an open connection.

I have encountered this particular issue in some production code that was listening for some data on a network. A customer firewall decided to rather crudely drop idle connections and left the entire connection thread pool of my application hanging forever. And that was it for the application... game over... server restart required.

Dealing with remote resources is always quite difficult but the code to do it is often done in haste. It's well worth taking some time to create a good integration module that is resilient to unexpected connection failures. Michael T Nygard's "Release It!" book is a great resource for these sorts of problems and discusses how you can guard yourself against them in some detail. I would highly recommend it.
+Pie Number of slices to send: Send
 

Mukesh Negi wrote:If while writing to the socket's output stream, the peer closes the connection (or because of some reason the connectivity is loosed), will my program wait infinitely or will it timeout after certain amount of time.

I searched a lot, but unable to find the answer.




Well, with TCP, if the peer closes the connection, it *should* be propagated back to the other side, and Java should report a connection reset. It other words, you *should* get an exception almost immediately.


However, this is a case of it being easier said than done. After all, it is dependent on actual networking equipment. There are lots of different types of equipment that may have compatibility issues; lots of hops though lots of equipment in-between (particularly if you are going through the internet); throw in some fire-walls, virus checkers, etc. and ... well, it may not actually work.

TCP tries to solve this issue with the timeout socket option (SO_TIMEOUT). The Java socket implementation does supports this, but you will need to enable it. With this option, there will be a delay, as it uses heartbeats to detect the lost connections. It won't be immediate, but again, it *should* work eventually.


However, this is further case of it being easier said than done. Unfortunately, not all networking equipment supports the heartbeats... so yea, it is possible for the connection reset to never be detected. If you want to guarantee the detection of the connection reset, you will have to implement an application level heartbeat / timeout mechanism into the protocol.

Henry
+Pie Number of slices to send: Send
 

Henry Wong wrote:Well, with TCP, if the peer closes the connection, it *should* be propagated back to the other side


Even in the best of situations I would consider this very wishful thinking.

The majority of network switching hardware sold today, or even ever, operates on the lower layers of the TCP stack. Primarily because it's cheap to do so. The downside of this is that the protocols of the higher layers in the TCP stack (the ones our Java applications work with) are not adhered to correctly, if any attempt is made at all. For the likes of you and me, good old "Johnny Developer", this means that all bets are off when it comes to network communication. You have to expect the worst, which could honestly be absolutely anything.

The real life example I put forward earlier with the Customer Firewall dropping connections: It did not close the connection nicely and notify the users on the ends of it. Oh no, it just dropped packets and said nothing. The applications thought the connections were still up, if not a bit quiet.
+Pie Number of slices to send: Send
Thanks for your replies..

According to my understanding SO_TIMEOUT is considered only when we are reading from the socket, I have tried this and it worked. The time_out parameter that we give in socket.connect method is the time_out only when establishing the connection.
I am more concern about when writing to the socket. I have read some where that write does not blocks but read does blocks.

My understanding on socket.write is following, please correct me if wrong:
When writing to socket it completely depends on the TCP buffer, I mean, if we are writing a small amount of data, then it will immediately wait on socket.read to read the acknowledgement and here SO_TIMEOUT will come into picture. This is so because we have completely written data to the buffer and hence our write operation is completed. But this is not the case with large data as our write operation does not get completed.
+Pie Number of slices to send: Send
 

Mukesh Negi wrote:
According to my understanding SO_TIMEOUT is considered only when we are reading from the socket, I have tried this and it worked. The time_out parameter that we give in socket.connect method is the time_out only when establishing the connection.
I am more concern about when writing to the socket. I have read some where that write does not blocks but read does blocks.

My understanding on socket.write is following, please correct me if wrong:
When writing to socket it completely depends on the TCP buffer, I mean, if we are writing a small amount of data, then it will immediately wait on socket.read to read the acknowledgement and here SO_TIMEOUT will come into picture. This is so because we have completely written data to the buffer and hence our write operation is completed. But this is not the case with large data as our write operation does not get completed.




Oops... my mistake. I meant the SO_KEEPALIVE socket option. Using this option, on a TCP socket, *should* enable checking at the switches for packets (or KA packets), and reset the socket when they timeout.

Regardless, as already mentioned, with the large mix of hardware (and network hops), this feature is not guaranteed to work in all cases. And if you want that guarantee, you will have to implement it into your protocol.

Sorry for the confusion,
Henry
+Pie Number of slices to send: Send
 

Henry Wong wrote:


Oops... my mistake. I meant the SO_KEEPALIVE socket option. Using this option, on a TCP socket, *should* enable checking at the switches for packets (or KA packets), and reset the socket when they timeout.

Regardless, as already mentioned, with the large mix of hardware (and network hops), this feature is not guaranteed to work in all cases. And if you want that guarantee, you will have to implement it into your protocol.

Sorry for the confusion,
Henry



Henry really thanks for your reply. Above, you have mentioned about SO_KEEPALIVE option, which is used to keep connection alive.

Henry, but I don't want to keep it alive. I want to break the write operation after specified time. The second thing you mentioned is about hardware, again same thing implies here as well. I just want to break the write after specified time.

Actually, I am using org.apache.commons.net.ftp api to deal with file uploading and downloading. And I am looking for the solution while uploading the file.
+Pie Number of slices to send: Send
 

Mukesh Negi wrote:
Henry really thanks for your reply. Above, you have mentioned about SO_KEEPALIVE option, which is used to keep connection alive.

Henry, but I don't want to keep it alive. I want to break the write operation after specified time. The second thing you mentioned is about hardware, again same thing implies here as well. I just want to break the write after specified time.




It's a bit confusing, but the KEEPALIVE option is used to detect failed connections that doesn't disconnect. With the option, keep alive packets are used because the switches will disconnect with the lack of data. If the connection fails, then even the keep alive packets will fail to send, so the switch should break the connection. In other words, this option does more than just send keep alive packets -- it should also change the behavior of the network components to break the connection after a certain timeout.


Having a timeout on a socket write is something else entirely. Your latest post now seems to imply that the socket is still up and running, and your problem is that the write is waiting the other side to drain the data -- which for some reason is not happening. If it is not a failed connection, and you just want to not work on a write indefinitely, then another option is to use a NIO socket channel in non blocking mode.

Henry



+Pie Number of slices to send: Send
 

Mukesh Negi wrote:
Actually, I am using org.apache.commons.net.ftp api to deal with file uploading and downloading. And I am looking for the solution while uploading the file.



Then you need to examine the docs for the class that you are using -- to see if there is an option that you want. There isn't much you can do, if the library you are using doesn't give you the option you want (besides using a different library).

Henry
Don't touch me. And dont' touch this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com


reply
reply
This thread has been viewed 3761 times.
Similar Threads
clarification needed on setSoTimeout()
Socket Time Out
Search on a string
how did java.net.* package deal with session?
Socket push..
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 28, 2024 17:26:04.