我在两个站点之间建立标准TCP连接(A,B) A正在发送消息,B接收并发回响应,然后我关闭连接。
有时B会没有发回响应,然后我需要重新尝试整个过程。
我想在A站的回放时间设置超时(等待B回答)。 所以基本上当等待时间到期时,我会发出重试。
我没有找到如何为DataInputStream设置超时的方法。 (仅适用于整个套接字连接 - 我不想要)
一些代码:
/**
* 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());
}
}
谢谢, 射线。
答案 0 :(得分:2)
考虑使用非阻止SocketChannel
而不是DataInputStream
。
示例:
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());
}
}
答案 1 :(得分:1)
首先查看socket.setSoTimeout(timeout)
其次,请参阅此讨论:Is it possible to read from a InputStream with a timeout?
读取方法被阻止。检查流是否包含数据而不阻塞的唯一方法是使用available()
方法。因此,您可以尝试以一定的延迟调用此方法,并在n秒后没有任何可用的情况下退出。您可以编写自己的输入流来包装实现此逻辑的任何其他输入流。上面的参考显示了如何执行此操作。