你如何干净地关闭 AsynchronousSocketChannel?
Posted
技术标签:
【中文标题】你如何干净地关闭 AsynchronousSocketChannel?【英文标题】:How do you close a AsynchronousSocketChannel cleanly? 【发布时间】:2014-01-11 19:44:32 【问题描述】:我的服务器使用AsynchronousServerSocketChannel
,它使用CompletionHandler
侦听客户端连接。当客户端连接被接受时,AsynchronousSocketChannel
被读取,再次使用CompletionHandler
接收数据,没有超时。
到目前为止一切顺利,我的客户端连接,写入服务器读取的数据,服务器能够响应通过同一个套接字将数据发送回客户端。
当我的客户端终止时,它会调用AsynchronousSocketChannel.close()
来关闭套接字。进行此调用时,服务器正在等待从套接字读取数据。
我曾预计客户端上对AsynchronousSocketChannel.close()
的调用会转换为对服务器上-1
的读取长度的CompletionHandler.completed
的回调,表明套接字已关闭,但回调是对@987654329 @ 除了以下例外:
java.io.IOException: The specified network name is no longer available.
at sun.nio.ch.Iocp.translateErrorToIOException(Iocp.java:309)
at sun.nio.ch.Iocp.access$700(Iocp.java:46)
at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:399)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
客户端应该如何关闭一个套接字,以便它在服务器上不被视为错误?
【问题讨论】:
【参考方案1】:documentation on close 表示它会导致 另一端的 AsynchronousCloseException 或 ClosedChannelException。
要引起completed(-1)
,客户端应该调用shutdownInput。
但是,我会将 AsynchronousCloseException 和 ClosedChannelException 视为正常关闭,以及 completed(-1)。
【讨论】:
它没有提到“另一边”。这两个异常都应该被视为编程错误,而不是“正常关机”。 我在客户端添加了对AsynchronousSocketChannel.shutdownInput
的调用,这确实会导致在服务器上以-1的读取长度回调CompletionHandler.completed
。
很遗憾客户端得到了一个AsynchronousCloseException
,尽管至少它不是很一般的IOException
,并且因为客户端启动了关闭,我可以添加一个closing
标志以便忽略此错误。
@EJP - 你知道完全避免AsynchronousCloseException
的方法吗?
我也被这种行为难住了...如果客户端使用有效方法关闭连接,为什么会抛出异常?我想知道。这就像您每次关闭车门时都会触发汽车警报一样......以上是关于你如何干净地关闭 AsynchronousSocketChannel?的主要内容,如果未能解决你的问题,请参考以下文章