views:

743

answers:

3

I have a simple badly behaved server (written in Groovy)

ServerSocket ss = new ServerSocket(8889);
Socket s = ss.accept()
Thread.sleep(1000000)

And a client who I want to have timeout (since the server is not consuming it's input)

Socket s = new Socket("192.168.0.106", 8889)
s.setSoTimeout(100);
s.getOutputStream.write( new byte[1000000] );

However, this client blocks forever. How do I get the client to timeout?

THANKS!!

+1  A: 

You could spawn the client in it's own thread and spin lock/wait(timeout long) on it to return. Possibly using a Future object to get the return value if the Socket is successful.

I do believe that the SO_TIMEOUT setting for a Socket only effects the read(..) calls from the socket, not the write.

You might try using a SocketChannel (rather then Stream) and spawn another thread that also has a handle to that Channel. The other thread can asynchronously close that channel after a certain timeout of it is blocked.

Gandalf
A: 

The socket timeout is at the TCP level, not at the application level. The source machine TCP is buffering the data to be sent and the target machine network stack is acknowledging the data received, so there's no timeout. Also, different TCP/IP implementations handle these timeouts differently. Take a look at what's going on on the wire with tcpdump (or wireshark if you are so unfortunate :) What you need is application level ACK, i.e. you need to define the protocol between client and the server. I can't comment on Java packages (you probably want to look at nio), but receive timeout on that ACK would usually be handled with poll/select.

Nikolai N Fetissov
A: 

There is no way to get the timeout, but you can always spawn a thread that closes the connection if the write hasn't finished.

Nuoji