如何连接和关闭插座?

问题描述:

我正在使用Java套接字客户端。在服务器仍然连接到我的客户端但它不会对我的消息发送响应的情况下 - 我最终会得到读取超时异常。如何连接和关闭插座?

在这种情况下,我想测试,看看我是否应该重新连接我的套接字或只是让它重新使用它。

我用这个条件:

if (!socket.isConnected() || socket.isClosed() || !socket.isBound()) { 
    try { 
     socket.close(); 
    } catch (IOException e1) { 
    } 
    // Wait on a new connection 
    socket = connectSocket(.....); 
} 

但我似乎总是重新连接。当我登录的布尔属性的值,我看到:

连接:真正的关闭:真正的约束:真

怎样才可以连接并关闭?

TIA

+0

方法调用不是原子的......也许另一个线程正在关闭isConnected()和isClosed()调用之间的套接字?也许首先同步套接字对象? – Powerlord 2010-09-13 14:02:24

+0

如果您只是将“isConnected()”和“isClosed()'的检查顺序颠倒过来,就很容易测试。 – 2010-09-13 14:15:23

This thread了关于该议题的一些有益的讨论。事实证明,Socket.isConnected如果(曾经)成功连接,则返回true。

从上面的线:

当您使用Socket(),你似乎都忽略了, Socket.isConnected()告诉你Socket.connect()是否已被称为 与否。对于isClosed()close()也是如此。

混淆这些方法从混淆 插座,这是应用程序的控制下的状态下,与整体连接,这是所述协议的控制下的状态结果 。 isConnected()isClosed()告诉你对套接字做了什么。 除了读取和写入之外,没有任何API用于确定连接的状态。

的文档说:

返回true,如果将套接字成功地连接到服务器

,而不是作为一个也许会想到“返回true,如果套接字连接到服务器“。

行为可以通过查看插座的来源得到证实:

public boolean isConnected() { 
    // Before 1.3 Sockets were always connected during creation 
    return connected || oldImpl; 
} 

你也可以运行这个小测试片段:

Socket s = new Socket(); 

System.out.println("isConnected: " + s.isConnected() + 
        " isBound: "  + s.isBound() + 
        " isClosed: " + s.isClosed()); 

s.connect(new InetSocketAddress("google.com", 80)); 

System.out.println("isConnected: " + s.isConnected() + 
        " isBound: " + s.isBound() + 
        " isClosed: " + s.isClosed()); 

s.close(); 

System.out.println("isConnected: " + s.isConnected() + 
        " isBound: " + s.isBound() + 
        " isClosed: " + s.isClosed()); 

它打印:

isConnected: false isBound: false isClosed: false 
isConnected: true isBound: true isClosed: false 
isConnected: true isBound: true isClosed: true 

我必须说,这个文档在这方面还不是很清楚,而且方法名称有点不明确isleading。

+11

+1布拉沃!很好的答案! – 2010-09-13 14:24:53

+2

谢谢。现在,我很清楚。 – sproketboy 2010-09-13 14:26:41

+0

破碎的链接,但从引用看来,它似乎已经从这里或在Sun/Oracle Java论坛的答案中解除了holus-bolus,其中很多都是由我来完成的。 – EJP 2017-07-06 01:35:05