【问题标题】:setting a timeout for an InputStreamreader variable为 InputStreamreader 变量设置超时
【发布时间】:2010-05-19 22:32:04
【问题描述】:

我有一个正在运行的服务器,它接受通过客户端套接字建立的连接,我需要从这个客户端套接字读取输入,现在假设客户端打开了与我的服务器的连接,而没有通过服务器的套接字输出流发送任何内容,在这种情况下,当我的服务器尝试通过客户端套接字的输入流读取输入时,将引发异常,但在引发异常之前我希望超时 5 秒,我该怎么做?目前这是我的代码在服务器端的样子:

try 
    {
        InputStreamReader clientInputStream = new InputStreamReader(clientSocket.getInputStream());
        int c;
        StringBuffer requestBuffer = new StringBuffer();
        while ((c = clientInputStream.read()) != -1) 
        { 
            requestBuffer.append((char) c);
            if (requestBuffer.toString().endsWith(("\r\n\r\n")))
                break;
        }
        request = new Request(requestBuffer.toString(), clientSocket);
    } 
    catch (Exception e) // catch any possible exception in order to keep the thread running
    {
        try 
        {
            if (clientSocket != null)
                clientSocket.close();
        } catch (IOException ex) 
        {
            ex.printStackTrace();
        }
        System.err.println(e);
        //e.printStackTrace();
    }

【问题讨论】:

    标签: java client webserver


    【解决方案1】:

    教科书的答案是在您的套接字上设置soTimeout,您可以这样做。但是,这并不适用于所有情况。我的一个朋友曾经通过拔出我的网线来证明这一点。我将 soTimeout 设置为 30 秒的值,但我的应用程序只是永远挂在那里。

    要获得可靠的超时,最好将 I/O 分离到另一个线程上。如果线程在给定时间内没有返回响应,您可以尝试中断它,关闭流并最终销毁线程。这不会让你更进一步,但会尝试清理流。一旦发生超时,您将需要考虑当前通信丢失,重新建立连接并重新发送先前的命令以重复通信。 command-pattern 可以在这里提供帮助。如果命令是幂等的并且可以多次执行,则执行起来会容易得多。能够重复失败的请求可用于处理间歇性 I/O 错误。

    【讨论】:

    • 很好,然后是 setSoTimeout,它在大多数情况下都有效,但如果它没有及时返回,也要准备好中断你的线程。请注意,在某些情况下,即使中断也不会让您的线程停止等待 I/O(我知道它应该,但实际上它不会)所以如果中断没有给你控制权,请准备好关闭流,放弃线程并重新开始一个新的连接。
    • 我想保持线程运行,因为它包含在我准备并在启动服务器时启动的线程池中。在我对布赖恩的评论中,我说异常仍然被立即抛出。
    • 我怀疑您的超时没有起作用,因为您在 连接已经创建之后设置了它。您需要 (a) 在套接字构造函数中包含超时,它会自动连接或 (b) 调用无参数套接字构造函数,然后调用 setSoTimeout,然后使用 SocketAddress 调用 socket.connect。请参阅 berni 的回答:stackoverflow.com/questions/6656666/…
    【解决方案2】:

    您是否尝试过在底层套接字上设置超时?见Socket.setSoTimeout()。来自文档:

    将此选项设置为非零 超时,read() 调用 与此关联的 InputStream 套接字将仅阻止此数量 的时间。如果超时到期,则 java.net.SocketTimeoutException 是 提出,虽然套接字仍然 有效

    【讨论】:

    • 不,但我现在尝试这样做:clientSocket.setSoTimeout(5000);但仍然会立即抛出异常。
    • 异常类和消息是什么?
    • java.net.SocketException: Connection reset and its source is this line: while ((c = clientInputStream.read()) != -1)
    • 也许这会有所帮助。 stackoverflow.com/questions/62929/…
    猜你喜欢
    • 2015-10-16
    • 1970-01-01
    • 1970-01-01
    • 2020-12-01
    • 2017-06-23
    • 2022-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多