如何删除/重新启动客户端连接到flaky socket服务器

时间:2009-08-13 16:07:12

标签: java sockets

我有Java代码,它通过来自用C ++编写的服务器的套接字发出请求。通信只是java代码为请求写一行,然后服务器在响应中写一行,但有时看起来服务器没有响应,所以我实现了一个基于ExecutorService的超时,试图丢弃和重启连接。

使用我保留的连接:

Socket server;
PrintWriter out;
BufferedReader in;

所以建立连接是一个问题:

server = new Socket(hostname, port);
out = new PrintWriter(new OutputStreamWriter(server.getOutputStream()));
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

如果不是超时代码,则请求/接收步骤只是:

String request="some request";
out.println(request);
out.flush();
String response = in.readLine();

当我收到超时时,我试图通过以下方式关闭连接:

in.close();
out.close();
socket.close();

但其中一个关闭似乎阻止而且永远不会返回。任何人都可以给我一个线索,为什么其中一个会阻止,什么是放弃连接的正确方法,而不是最终导致资源泄漏问题?

3 个答案:

答案 0 :(得分:0)

关闭包装套接字的缓冲读写器将关闭套接字 关闭已经关闭的套接字是不正确的,但它应该不是问题。

无论如何,根据java socket: 一旦套接字关闭,它就不能用于进一步的网络使用(即不能重新连接或反弹)。需要创建一个新的套接字。

因此,您需要在关闭此套接字后创建一个新的套接字对象。

就你的内存管理而言,垃圾处理程序应该为你杀掉旧的,所以不要担心泄漏。

答案 1 :(得分:0)

对out.close()的调用可能会阻塞,因为PrintWriter.close()方法在与println(String)方法相同的锁上同步。如果对println的原始调用被阻止尝试写入错误连接,则无法对其进行close()调用。

您是否尝试过使用Socket.setSoTimeout()方法?

答案 2 :(得分:0)

我认为你只需要关闭套接字(然后相应地处理读/写线程中的任何异常)。另外,如上所述,从头开始重新创建套接字。