I am establishing standart TCP connection between two stations(A,B) A is sending message, B recieving and sending response back, and then I close the connections.
- Stations B is "blackbox", I cant access change or do anyt开发者_StackOverflow社区hing there.
Sometimes there is situation when B didnt send response back, and then I need to re-try the whole process again.
I want to set timeout on the reciveing time of Station A (which wait for B for an answer). So basically when the waiting time is expired, i will dispatch a retry.
I didnt find a way how to set a timeout for DataInputStream. (only for the whole socket connection - which I dont want)
some code:
/**
* Method receives the Server Response
*/
public byte[] receive(DataInputStream is) throws Exception
{
logger.debug(TAG + " Client Recieving...");
try
{
byte[] inputData = new byte[1024];
// here I want to set timeout for the "receiving mode"
is.read(inputData);
return inputData;
} catch (Exception e)
{
throw new Exception(TAG + " Couldnt receive data from modem: " + e.getMessage());
}
}
Thanks, ray.
First check out socket.setSoTimeout(timeout)
Second, see this discussion: Is it possible to read from a InputStream with a timeout?
read method is blocked. The only way to check whether stream contains data without blocking is using available()
method. So you can try to call this method with certain delay and exit if nothing is available after n seconds. You can write your own input stream that wraps any other input stream implementing this logic. The reference above shows how to do this.
Consider using a non-blocking SocketChannel
instead of a DataInputStream
.
Example:
private static final long TIMEOUT = 500;
/**
* Method receives the Server Response
*/
public <C extends SelectableChannel & ReadableByteChannel>byte[]
receive(C chan) throws IOException
{
logger.debug(TAG + " Client Recieving...");
try
{
Selector sel = Selector.open();
SelectionKey key = chan.register(sel, SelectionKey.OP_READ);
ByteBuffer inputData = ByteBuffer.allocate(1024);
long timeout = TIMEOUT;
while (inputData.hasRemaining()) {
if (timeout < 0L) {
throw new IOException(String.format("Timed out, %d of %d bytes read", inputData.position(), inputData.limit()));
}
long startTime = System.nanoTime();
sel.select(timeout);
long endTime = System.nanoTime();
timeout -= TimeUnit.NANOSECONDS.toMillis(endTime - startTime);
if (sel.selectedKeys().contains(key)) {
chan.read(inputData);
}
sel.selectedKeys().clear();
}
return inputData.array();
} catch (Exception e)
{
throw new Exception(TAG + " Couldnt receive data from modem: " + e.getMessage());
}
}
精彩评论