tags:

views:

368

answers:

3

I've got Java code which makes requests via sockets from a server written in C++. The communication is simply that the java code writes a line for a request and the server then writes a line in response, but sometimes it seems that the server doesn't respond, so I've implemented an ExecutorService based timeout which tries to drop and restart the connection.

To work with the connection I keep:

Socket server;
PrintWriter out;
BufferedReader in;

so setting up the connection is a matter of:

server = new Socket(hostname, port);
out = new PrintWriter(new OutputStreamWriter(server.getOutputStream()));
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

If it weren't for the timeout code the request/receive steps are simply:

String request="some request";
out.println(request);
out.flush();
String response = in.readLine();

When I received a timeout I was trying to close the connection with:

in.close();
out.close();
socket.close();

but one of these closes seems to block and never return. Can anyone give me a clue why one of these would block and what would be the proper way to abandon the connection and not end up with resource leak issues?

A: 

Closing the buffered reader/writer that wraps the socket will close the socket.
Closing an already closed socket isn't correct, but it shouldn't be a problem.

Anyways, according to java socket: Once a socket has been closed, it is not available for further networking use (i.e. can't be reconnected or rebound). A new socket needs to be created.

So you need to make a new socket object after you close this one.

As far as your memory management goes, the garbage handler should kill your old one for you, so don't worry about a leak.

windfinder
A: 

The call to out.close() may block because the PrintWriter.close() method is synchronized on the same lock as the println(String) method. If the original call to println is blocked trying to write to a bad connection, you won't be able to call close() on it.

Have you tried using the Socket.setSoTimeout() method?

joe p
I didn't try calling setSoTimeout(), however it sounds like it only affects a read call, if I'm blocked in the write call (which is sounds like I am given the out.close() also blocking) it won't help me - correct?
Steve Prior
A: 

I think you only need to close the socket (and then handle any Exceptions in the read/write thread accordingly). Also, as said above, recreate the socket from scratch.

Mirvnillith