一个socket如何既能连接又能关闭?

32
我正在使用Java socket客户端。在服务器仍连接到我的客户端但没有响应我的消息的情况下,我最终会收到读取超时异常。
在这种情况下,我想测试一下是否应该重新连接我的socket或者只是保持它并重用它。
我使用以下条件:
if (!socket.isConnected() || socket.isClosed() || !socket.isBound()) {
    try {
        socket.close();
    } catch (IOException e1) {
    }
    // Wait on a new connection
    socket = connectSocket(.....);
}

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

connected: true closed: true bound: true

如何同时连接和关闭呢?

TIA


方法调用不是原子性的……也许另一个线程在 isConnected()isClosed() 调用之间关闭了套接字?也许先在套接字对象上同步? - Powerlord
如果你只是反转 isConnected()isClosed() 的检查顺序,那么测试起来就很容易。 - Erick Robertson
1个回答

85

这个线程讨论了这个话题并提供了一些有用的讨论。事实证明,Socket.isConnected如果连接成功过就会返回true。

从上面的线程中可以得到以下信息:

当你使用 Socket() 时,你似乎忽略了一个细节,Socket.isConnected() 告诉你是否已经调用了Socket.connect()。对于isClosed()close()方法同理。

混淆了这些方法的结果是混淆了应用程序控制的套接字(socket)的状态与协议控制的整个连接的状态。 isConnected()isClosed() 方法告诉你你对套接字做了什么操作。除了read和write之外,没有其他API可用于确定连接的状态。

文档说明如下:

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

而不是像人们可能期望的那样 "如果套接字已连接到服务器,则返回true。"。

可以通过查看Socket源代码来确认这种行为:

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

我必须说,关于这一点的文档说明相当不清楚,并且方法名称有点误导性。


链接已损坏,但从引用中看来,它似乎是整个地从这里或Sun/Oracle Java论坛的答案中提取的,其中许多是由我提供的。 - user207421
1
好的回答。我也对isConnected感到困惑。 - Chintan Rathod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接