[英]How do you set a timeout on BufferedReader and PrintWriter in Java 1.4?
如何在使用套接字连接创建的 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));
}
}
在此代码的 scope 之外,我设置了 1000 毫秒的套接字超时,这在等待初始连接时按预期工作。 但是程序在 (str = br.readLine()) 处阻塞。 如果客户端挂起或崩溃,它永远不会停止阻塞,除非我终止进程(即使那样也不总是有效)。
有问题的客户端代码与此非常相似,并且以类似的方式阻塞。
您可以使用 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
}
您需要使用Socket.setSoTimeout()
在套接字上设置读取超时。 如果指定的读取超时过期,这将导致任何读取方法抛出SocketTimeoutException
。 注意 读取超时不是在 stream 上设置的,而是通过 Socket.setSoTimeout() 在底层Socket,
上设置的Socket.setSoTimeout().
TCP 中没有写超时之类的东西。
这个问题的答案描述了一种使用Timer
关闭连接的有趣方法。 我不是 100% 确定这在阅读过程中是否有效,但值得一试。
从那个答案复制:
TimerTask ft = new TimerTask(){
public void run(){
if (!isFinished){
socket.close();
}
}
};
(new Timer()).schedule(ft, timeout);
isFinished
应该是一个boolean
变量,当您从 stream 读取完毕后,该变量应设置为true
。
由于调用 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));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.