手动设置DataInputStream的超时

发布于 2024-10-11 14:05:17 字数 798 浏览 2 评论 0原文

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

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

谢谢, 射线。

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 anything 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

幻想少年梦 2024-10-18 14:05:17

首先查看 socket.setSoTimeout(timeout)

其次,请参阅此讨论:是否可以从具有超时的输入流中读取?

读取方法被阻止。检查流是否包含数据而不阻塞的唯一方法是使用 available() 方法。所以你可以尝试以一定的延迟调用这个方法,如果n秒后没有可用的则退出。您可以编写自己的输入流来包装实现此逻辑的任何其他输入流。上面的参考显示了如何执行此操作。

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.

夜未央樱花落 2024-10-18 14:05:17

考虑使用非阻塞 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());
    }
}

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());
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文