views:

539

answers:

5

In java when you close a socket it doesn't do anything anymore but it actually closes the tcp connection after a timeout time. I need thousands of sockets and I want them to be closed exactly after closed them not after wasting my time and my resources! What can I do?

Thank you.

+2  A: 

If you're running a server, then ServerSocket is the proper solution. It will manage everything better than you doing it by hand through recycling and a host of other optimizations intended for running a server with Java.

Closing the socket disconnects the Java object from the operating system, which means that it isn't taking up any resources outside of the JVM, so it really shouldn't be a problem. But if the minimal overhead from Java's garbage collection/finalization scheme is too big of a burden, then Java isn't a valid solution (since your problem isn't specific to socket programming any more). Although I have to say that an efficient garbage collector is not much worse than explicitly managing memory (and can actually perform better).

Travis Gockel
Both ends should be efficient for my task.
Shayan
+1  A: 

I found out. using socket.setReuseAddress(boolean) you can tell the jvm to reuse the port even if it's in the timeout period.

Shayan
A: 

call the method shutdownOutput() before/instead of calling close() on the Socket.

For a TCP socket, any previously written data will be sent followed by TCP's normal connection termination sequence.

The other side should also confirm the termination causing an EOF when trying to read from the socket, now you can close the socket.

EDIT:
sorry, I was wrong, shutdownOutput() will not be of much help for this question.

It is useful if you have a reading thread blocked waiting to read data from the socket, and want to close the connection (from another thread. Calling close() in that situation would cause the reading method to get an IOException (socket closed).

The solution I found to avoid this exception is:

  1. call shutdownOutput() which will close the transmit half of the connection,
  2. the other side will get an EOF (actually its read method, assuming there is one blocked),
  3. the other side should close the socket,
  4. the reading Thread on this side will leave the blocked read (with an EOF),
  5. this side can also close the socket.
Carlos Heuberger
But still you can not bind on that port.
Shayan
Nope. Calling `close` does that already. Per the documentation of `Socket.close()` : "Closing this socket will also close the socket's InputStream and OutputStream."
Travis Gockel
Yes but don't unbind the port.
Shayan
@Travis : but `close` will abort the connection, not doing a normal termination. On the *other side*, if reading with a java socket, `close` causes an `IOException`, `shutdownOutput` causes an `EOF`.
Carlos Heuberger
Not exactly. See the accepted answer from here: http://stackoverflow.com/questions/41602/how-to-forcibly-close-a-socket-in-timewait
Shayan
@Interruption Duck: That doesn't make sense. EOF is client-imposed and OS-dependent (although it is universally -1, there isn't a magic network EOF value). An `InputStreamReader` will start reading EOF no matter what system transmitted the packet. Just to be sure, I wrote a quick app and tested calling `shutdownOutput()` and then `close()` and then just calling `close()` and used a packet sniffer to see the transmission, which was identical. Then I tried just calling `shutdownOutput()` . As expected, this renders that port unusable for the lifetime of the virtual machine.
Travis Gockel
@Travis: Thanks, you are correct, my mistake. I had another problem in my mind. Edited the answer to reflect that. (*I would down vote the answer if I could* :-| )
Carlos Heuberger
A: 

'I want them to be closed exactly after closed them not after wasting my time and my resources!' No you don't. You want TCP/IP to work correctly, and the TIME_WAIT state is a critically important part of that. If you're worried about the TIME_WAIT state, the quick answer is to be the one who receives the FIN rather than the one who first sends it.

EJP
A: 

I think better way is to make the socket as null

Thanks Sunil Kumar Sahoo

Deepak