我有一台运行的服务器接受通过客户端套接字建立的连接,我需要读取来自此客户端套接字的输入,现在假设客户端打开了与我的服务器的连接而没有通过服务器的套接字输出流发送任何内容,在这种情况下,当我的服务器尝试通过客户端套接字的输入流读取输入时,会抛出异常,但在抛出异常之前我想要超时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();
}
答案 0 :(得分:3)
教科书的答案是在你的套接字上设置soTimeout,你可以这样做。但是,这并不适用于所有情况。我的一个朋友曾经通过拉出我的网线证明了这一点。我将soTimeout
设置为30秒,但我的应用程序只是挂在那里,永远。
要获得可靠的超时,最好将I / O分离到另一个线程。如果线程在给定时间内没有回复响应,您可以尝试中断它,关闭流并最终销毁线程。这不会让你更进一步,但会尝试清理流。一旦发生超时,您将需要考虑当前通信丢失,重新建立连接并重新发送上一个命令以重复通信。 command-pattern可以在这里提供帮助。如果命令是幂等的并且可以多次执行,则更容易做到。能够重复失败的请求可用于处理间歇性I / O错误。
答案 1 :(得分:0)
您是否尝试过在底层套接字上设置超时?见Socket.setSoTimeout()。来自doc:
将此选项设置为非零 超时,对()的read()调用 与此相关的InputStream 套接字将仅阻止此数量 时间如果超时到期,a java.net.SocketTimeoutException是 虽然Socket仍然存在但仍然提升了 有效