如何在Java 1.4中设置BufferedReader和PrintWriter的超时?

Ben*_*est 14 java sockets java1.4 bufferedreader printwriter

如何在使用套接字连接创建的BufferedReader和PrintWriter上设置超时?这是我现在为服务器提供的代码,直到服务器或客户端崩溃为止:

while(isReceiving){
    str = null;
    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);

    while ((str = br.readLine()) != null){
        System.out.println("Processing command " + str);
        pw.println(client.message(str));
    }
}
Run Code Online (Sandbox Code Playgroud)

在这段代码的范围之外,我已经施加了1000毫秒的套接字超时,它在等待初始连接时按预期工作.但程序阻塞在(str = br.readLine()).如果客户端挂起或崩溃,它永远不会停止阻止,除非我终止进程(即使这样也不总是有效).

有问题的客户端代码与此非常相似,并且以类似的方式阻塞.

Phi*_*das 16

您可以使用Google的Guava库中的SimpleTimeLimiter.

示例代码(在Java 8中):

BufferedReader br = ...;
TimeLimiter timeLimiter = new SimpleTimeLimiter();

try {
    String line = timeLimiter.callWithTimeout(br::readLine, 10, TimeUnit.SECONDS);
} catch (TimeoutException | UncheckedTimeoutException e) {
    // timed out
} catch (Exception e) {
    // something bad happened while reading the line
}
Run Code Online (Sandbox Code Playgroud)

  • ...Java 8. 这个问题说的是 Java 1.4。 (2认同)
  • 只有相关的`read()`方法可中断时,番石榴代码才有效。不是java.net.Socket读取。 (2认同)

use*_*421 11

  1. 您需要在套接字上设置读取超时Socket.setSoTimeout().SocketTimeoutException如果指定的读取超时到期,这将导致任何读取方法抛出a .NB读取超时不是设置在流上,而是设置在底层Socket,通道上Socket.setSoTimeout().

  2. 在TCP中没有写入超时这样的事情.


tsk*_*zzy 5

这个问题的答案描述了一种使用 aTimer关闭连接的有趣方法。我不是 100% 确定这在阅读过程中是否有效,但值得一试。

从那个答案复制:

TimerTask ft = new TimerTask(){
   public void run(){
     if (!isFinished){
       socket.close();
     }
   }
};

(new Timer()).schedule(ft, timeout);
Run Code Online (Sandbox Code Playgroud)

isFinished应该是一个boolean变量,true当您完成从流中读取时应设置为该变量。


Ben*_*est 2

由于调用 socket.close() 似乎没有中断 br.readLine() 处的块,因此我做了一些解决方法。当断开客户端与服务器的连接时,我只需发送一个字符串“bye”,并告诉服务器在收到此命令时关闭套接字连接。

while ((str = br.readLine()) != null){
    // If we receive a command of "bye" the RemoteControl is instructing
    // the RemoteReceiver to close the connection.
    if (str.equalsIgnoreCase("bye")){
        socket.close();
            break;
    }
    System.out.println("Processing command " + str);
    pw.println(client.message(str));
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你可以发送“bye”,你可以关闭套接字,这将导致对等方的 readLine() 返回 null。很难看出这如何解决你所说的问题。 (4认同)