为DataInputStream手动设置超时

时间:2011-01-12 10:01:24

标签: java network-programming

我在两个站点之间建立标准TCP连接(A,B) A正在发送消息,B接收并发回响应,然后我关闭连接。

  • B站是“blackbox”,我无法进行更改或在那里做任何事情。

有时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());
    }
}

谢谢, 射线。

2 个答案:

答案 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秒后没有任何可用的情况下退出。您可以编写自己的输入流来包装实现此逻辑的任何其他输入流。上面的参考显示了如何执行此操作。