Is this possible with Java Sockets? setSoTimeout

Hello everyone.

I'm not sure what I should be trying to use here but I looked in the API and I think this is the closet thing to what I need.

What i'm trying to do is the following:

Everytime I send somthing from a client to a socket or vice versa I want to do the following:

Open the socket to send the String to the server

Like this:

outputServ =new Socket("localhost", 1234);

//Setting up channel to send data to outputserv

BufferedWriter out =new BufferedWriter(new OutputStreamWriter(outputServ

.getOutputStream()));

Now once I send that string to the server I need to wait for acknowledgment from that server that yes it got the String, and to send the next string, if it didn't get the string, resend it. So either way before I send the next string through the socket I need to get that acknowledgement, weither its a good or bad one.But I would like to set a time to wait for a response from the server.

So I set up my InputStreamWriter...

BufferedReader in =new BufferedReader(new InputStreamReader(

outputServ.getInputStream()));

So can I set code to say, if in.read() doesn't get any type of value back from the server within 10 seconds to resend the message through the output stream, (out) ?

I realize TCP does something similar but we must follow this protocol so customers can't complain if somthing bad does happen, i'm just a co-op at this company so I basically have to follow what they say.

I found this, I think it might help but I wasn't sure how to apply it:

12.1.4.1. SO_TIMEOUT

The SO_TIMEOUT option sets a timer on all I/O methods of a socket that block so that you don't have to wait forever if they don't return. This works for operations such as accept() on server sockets and read() or write() on all sockets. If the timer expires before the operation would complete, an InterruptedIOException is thrown. You can catch the exception and continue to use the socket normally if it is appropriate, or you can take the opportunity to bail out of the operation.

Could I catch that excpetion if it does time out and in that exception block some how tell it to resend (write) the string to the socket again?

[2485 byte] By [lokiea] at [2007-11-27 10:19:26]
# 1

> This works for operations such as accept() on server sockets and read() or write() on all sockets.

Socket.setSoTimeout(). It works on accept() and read(), but not on write(). (There is no write timeout in TCP/IP unless you use NIO, non-blocking mode, and a Selector.) If the timer expires you get a SocketTimeoutException. You can catch it and retry or whatever you need to do. Note however that TCP doesn't lose data so if you succeed in sending a retry for a string it definitely means the server will receive it twice, so the server transactions need to be idempotent. Or else you need to educate your customer better about TCP.

ejpa at 2007-7-28 16:57:39 > top of Java-index,Core,Core APIs...
# 2

Thanks for the responce ejp.

I noticed you said it won't work for write(). But for read() it will. Isn't this all I would need for my program?

Like say I write a string to the server:

out.write(msg.toString());

then wouldn't I only need a time out on the read() from that socket? To see if in.readLine() has a value, if it does, then that means I got some data back either telling me to send the message again or to go on with the processes or a time out, meaning the server, never send me back an acknowledgment.

lokiea at 2007-7-28 16:57:39 > top of Java-index,Core,Core APIs...
# 3

Have you considered the case when server accepts the client request, and sends acknowlegment, but it arrives just after the client's timeout has cause the client to resend the request?

TCP was designed for reliable transfer of bytes from endpoint to endpoint, and deals with problems like these in its implementation.

(not 100% sure about this one..:)

Maybe the best way to program with it is to recognize only 2 cases:

a) everything was sent and received correctly (server sends acknowledgment before client timer expired)

b) something wrong happened. In this case break the current operation and rollback to last safest point and report the error or start again, perpahs with a new connection.. of course, if application logic allows this..

boruthadzialica at 2007-7-28 16:57:39 > top of Java-index,Core,Core APIs...
# 4

Thanks for the suggestion!

lokiea at 2007-7-28 16:57:39 > top of Java-index,Core,Core APIs...
# 5

I do exactly that here, its not working just right yet but I think it will once I get a bug figured out on why its not sending the server any data...

try {

cSocket.setSoTimeout(5000);// time out in 5 seconds

// sending data to server

out.write(msg.toString()+'\n');

System.out.println("Waiting for ACK from Output Server...");

// waiting to get Acknowledgement from the server

String line;

while ((line = in.readLine()) != null) // If we get a line

{

System.out.println(line);

}

// else its going to throw an exception which will be

// caught outside this function.

}

catch (SocketTimeoutException sE) {

System.out.println("Didn't get Ack from server, trying again..");

socketSend(msg);

}

lokiea at 2007-7-28 16:57:39 > top of Java-index,Core,Core APIs...
# 6

You should terminate the connection when you get the timeout and form a new one.

And 5 seconds is far too short a timeout.

But I think you should educate your client about TCP.

And you need to flush the output before you try to read the response.

You will also have to put a counter of the number of times you do this so it doesn't get silly.

ejpa at 2007-7-28 16:57:39 > top of Java-index,Core,Core APIs...
# 7

Great idea ejp!

that way it won't hang forever.

I agree ejp, I guess I'm ahead of schedule on the design of this so once we have a meeting hopefully more people will listen to me about the TCP issue and how I don't need this feature at all. Which will really save a lot of time sending the events to the server.

lokiea at 2007-7-28 16:57:39 > top of Java-index,Core,Core APIs...