java 套接字如何既连接又关闭?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3701073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 03:03:34  来源:igfitidea点击:

How can a socket be both connected and closed?

javasockets

提问by sproketboy

I'm using a Java socket client. In a case where the server is still connected to my client but it does not send a response to my message - I eventually get a read time out exception.

我正在使用 Java 套接字客户端。在服务器仍然连接到我的客户端但它没有发送对我的消息的响应的情况下 - 我最终会收到读取超时异常。

In that case I want to test to see if I should reconnect my socket or just keep it an re-use it.

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

I use this condition:

我使用这个条件:

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

But I always seem to reconnect. When I log the values of the Boolean properties I see this:

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

connected: true closed: true bound: true

连接:真 封闭:真 界限:真

How can it be connected and closed?

它如何连接和关闭?

TIA

TIA

回答by aioobe

This threadhas some useful discussions on this topic. It turns out that Socket.isConnectedreturns true if it has (ever) been successfully connected.

该线程对此主题进行了一些有用的讨论。事实证明,Socket.isConnected如果(曾经)成功连接,则返回 true。

From the above thread:

从上面的线程:

When you use Socket(), which you seem to have overlooked, Socket.isConnected()tells you whether Socket.connect()has been called or not. Similarly for isClosed()and close().

Confusion over these methods results from confusing the state of the socket, which is under the control of the application, with the state of the overall connection, which is under the control of the protocol. isConnected()and isClosed()tell what you have done to the socket. There are no APIs other than read and write for determining the state of the connection.

当您使用 时Socket(),您似乎忽略了这一点,它会 Socket.isConnected()告诉您是否Socket.connect()已被调用。isClosed()和类似close()

对这些方法的混淆是由于将受应用程序控制的套接字状态与受协议控制的整体连接状态混淆了 。 isConnected()isClosed()告诉您对套接字做了什么。除了用于确定连接状态的读取和写入之外,没有其他 API。

The docs says:

文档说:

Returns true if the socket successfuly connected to a server

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

and not as one perhaps would expect "returns true if the socket is connected to a server".

而不是人们可能期望的“如果套接字连接到服务器则返回真”。

The behavior can be confirmed by looking at the source of Socket:

可以通过查看 Socket 的来源来确认该行为:

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

You could also run this little test snippet:

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

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());

Which prints:

哪个打印:

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

I must say that the documentation is quite unclear on this point, and that the method-name is a bit misleading.

我必须说文档在这一点上很不清楚,并且方法名称有点误导。