且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java 套接字 API:如何判断连接是否已关闭?

更新时间:2022-06-20 09:12:02

没有 TCP API 会告诉您连接的当前状态.isConnected()isClosed() 告诉您套接字的当前状态.不是一回事.

There is no TCP API that will tell you the current state of the connection. isConnected() and isClosed() tell you the current state of your socket. Not the same thing.

  1. isConnected() 告诉你是否已经连接了这个socket.你有,所以它返回 true.

  1. isConnected() tells you whether you have connected this socket. You have, so it returns true.

isClosed() 告诉你是否已经关闭了这个套接字.直到你关闭,它返回false.

isClosed() tells you whether you have closed this socket. Until you have, it returns false.

如果peer已经有序地关闭了连接

  • read() 返回 -1
  • readLine() 返回 null
  • readXXX() 为任何其他 XXX 抛出 EOFException.

  • read() returns -1
  • readLine() returns null
  • readXXX() throws EOFException for any other XXX.

写入将抛出 IOException: 'connection reset by peer',最终会受到缓冲延迟的影响.

A write will throw an IOException: 'connection reset by peer', eventually, subject to buffering delays.

如果连接因任何其他原因断开,写入将抛出 IOException,最终,如上所述,读取可能会做同样的事情.

If the connection has dropped for any other reason, a write will throw an IOException, eventually, as above, and a read may do the same thing.

如果对端仍然连接但未使用连接,则可以使用读取超时.

If the peer is still connected but not using the connection, a read timeout can be used.

与您可能在别处读到的内容相反,ClosedChannelException 不会告诉您这一点.[SocketException: socket closed 也没有.]它只告诉你关闭了通道,然后继续使用它.换句话说,您的编程错误.它并不表示关闭的连接.

Contrary to what you may read elsewhere, ClosedChannelException doesn't tell you this. [Neither does SocketException: socket closed.] It only tells you that you closed the channel, and then continued to use it. In other words, a programming error on your part. It does not indicate a closed connection.

在 Windows XP 上对 Java 7 进行的一些实验结果表明,如果:

As a result of some experiments with Java 7 on Windows XP it also appears that if:

  • 您正在OP_READ
  • 上选择
  • select() 返回大于零的值
  • 关联的 SelectionKey 已经无效 (key.isValid() == false)
  • you're selecting on OP_READ
  • select() returns a value of greater than zero
  • the associated SelectionKey is already invalid (key.isValid() == false)

这意味着对等方已重置连接.但是,这可能是 JRE 版本或平台所特有的.

it means the peer has reset the connection. However this may be peculiar to either the JRE version or platform.