The documentation says that Socket's setSoTimeout(int) method
throws SocketException - if there is an error in the underlying protocol, such as a TCP error
Have you ever caught this exception? When using TCP sockets, what kind of TCP error could make this method throw the exception?
EDIT:
Let me try to be a bit more specific and deeper. I'm not looking for the trivial (eg, a closed socket will throw this exception) that can be easily found elsewhere.
Suppose the Socket (representing a TCP connection) has just been created, is connected, and not yet closed. I've not yet performed any reads/writes on it. I'm running on Linux (Ubuntu Server 11.04), so we can forget the case in which the TCP implementation doesn't support read timeouts.
Now, can this exception be thrown in this situation? If so, what does it mean? Is it something specific to the current Socket instance? If I simply close() it and somehow obtain a new one, should it work? Is it a bigger problem I cannot recover from (such as a problem in the operating system), and should better shutdown my application?
The SocketException, in this scenario, is either thrown if the socket is closed or closing.
It can also be thrown to indicate an error that was generated by the native TCP stack implementation. If, for instance, you are on Windows, setSoTimeout will likely boil down to an invocation of the setsockopt function in the Windows Winsock API. An error from this method would indicate some deeper issue in the winsock subsystem (unable to initialize) or it could also be thrown if you attempt to set socket options when a blocking operation is in progress on the socket (by another thread, for instance). For this reason, you should strive to only modify socket options at creation time, avoiding to change any options once you've connected the socket and started doing I/O on it.
You can read more here if you are curious.
java.net.SocketExceptionis thrown when you call setSoTimeout on a closed socket.
As always, use the forc..source.
Related
I'm writing a client-server application, using java TCP sockets.
Client and server are connected by a socket.
Sometimes server has to write a reply message for the client on this socket.
But in that moment, client's socket could be closed, not using close() method, but closing client's application.
Can you tell me, how server can recognize this situation, and avoid writing his reply message on this socket?
This is impossible to do reliably. If you establish that a connection is open, by the time you get around to writing to it, it may have been closed. The reliable solution is to attempt the write, and handle any errors that may result.
Note that if you do get an error indication, there is no saying how much data got to the remote peer. If you perform two writes, and the second write gets an error indication, it is quite possible that the remote peer shut down before the first write but the local peer only noticed it during the second write.
The answer, here, by Stephen C very well describes the issue. He says Broken pipe exception is caused by something causing the connection to close, and its not the application. I want to know what all this "something" could be in general, which is causing the connection to close? And what are the possible ways to handle them?
My usage environment:
I am running my application on set of machines on Azure, and all of them are talking to one of the machine. I am getting this error almost always.
Could TCP timeout be one of the reasons? If yes then how to make Socket Channels(in affect Socket running behind them) never close dues to TCP timeout?
You can get the socket associated with SocketChannel and then set its keepAlive property. Something like this.
SocketChannel sockChannel;
/*
connect here
*/
sockChannel.socket().setKeepAlive(true);
Broken pipe exception comes whenever client moves away from the socket on which it is listening. This might be due to socket timeout reached on client side as server was responding slow. Say, in case of a browser if any http request is taking long to respond and user closes the browser a broken pipe exception will be visible in application logs.
Now to resolve this either you increase socket timeout or fix you server response.
I have a thread that writes to a TCP socket every 5 sec., connected to a remote TCP port (using Java .net socket, not NIO). For your information I have not configured any timeout (S0,..) on to the socket layer, it's having the default values. If the network cable connected to remote TCP port
is removed my java thread is not getting any IO exception, rather it keeps writing to the socket.
Can somebody guide me why am I not getting those exceptions? I guess write method should through IOException while trying to write to the socket every 5 sec.
Regards, Rajib
This depends entirely an how much you write to the socket, in case you don't flush regurarly. If you write only a couple of bytes every 5 seconds, it may indeed take quite a bit for the buffer to fill and flush automatically. The exception should arise eventually. If you do flush, then there could be another network pipe that you are overlooking, such as WiFi, and the transport just fails over to that one.
It was silly of me not to dump the stuck trace while catching the IOException from socket.accept() and shutting down the thread doing the accept... Having fixed this, I still want to understand how to deal with the situation when this call barfs.
My app is a classic socket server accepting hundreds of clients, sometimes thousands. Accepting thread is always up and blocked in accept() call. Once accepted, the separate thread gets launched to do the stuff and so on. Nothing special.
The question is, what should be done when accept() fails? Should this be considered as a permanent failure immediately? Should I retry to get into accept() for some time and try to get through? What's the best practice? And what normally the reasons for the IOException to be thrown?
Its the clients responsibility to retry on connection failure. The server should just log the exception and continue back doing "accept". Servers in general, never initiate connections to client.
There are too many reasons for IOException to be thrown, from firewall issues to file-handle-exhaustion issues. The message of the IOException should reveal the cause.
The only reasons I can think of for an IOException being thrown in accept() call would be some issue with the port being in use or the host's networking being misconfigured.
You could potentially wait a bit and retry on the assumption that the system's administrator will notice the problem and fix it. But if this happens during startup, it would be a good idea for the application to bail out with a "fatal" error message.
I have a single-threaded non-blocking socket IO server written in Java using nio.
When I have finished writing to a connection, I want to close it.
Does the closing of the channel mean blocking until all buffered writes have been acknowledged by the recipient?
It would be useful to know if, when asynchronously closing, it succeeded or not, but I could live with any errors in the closing being ignored.
Is there any way to configure this, e.g. with setSoLinger() (and what settings would be appropriate?)
(A general discussion beyond Java about Linux and other OS in this respect would be useful to)
Closing in non-blocking mode is non-blocking.
You could put the channel into blocking mode, set a positive linger timeout, and close, and that would block for up to the linger timeout while the socket send buffer was being emptied, but alas Java doesn't throw an exception if the linger timeout expires, so you can't know whether all the data has gone. I reported this bug ten or more years ago and it came back 'will not fix' because of compatiblity concerns. If you can wait until Java 7 comes out I believe the nio2 stuff has this fixed, I certainly requested it, but who knows when that will be?
And even if you have all that, all you know is that the data was sent. You don't know anything about it being received or processed by the recipient application. If you need that you have to build it into your application protocol.
I'm not sure what really happens but I know that close() includes flush() (except in PrintStream and PrintWriter...).
So my approach would be to add the connections to close to a queue and process that queue in a second thread (including error handling).
I understand that your server is single-threaded but a second thread doesn't cost that much, the complexity of the problem is low and the solution will be easy to understand any maintain.