我的服务器使用AsynchronousServerSocketChannel,它使用CompletionHandler侦听客户端连接。当客户端连接被接受时,AsynchronousSocketChannel就会被读取,再次使用CompletionHandler来接收数据而没有超时。
到目前为止,我的客户端连接、写入由服务器读取的数据,服务器能够响应通过同一个套接字将数据发送回客户端。
当我的客户端终止时,它调用AsynchronousSocketChannel.close()来关闭套接字。当进行此调用时,服务器正在等待从套接字读取数据。
我原以为客户机上对AsynchronousSocketChannel.close()的调用将转换为对CompletionHandler.completed的回调,服务器上的读取长度为-1,指示套接字已关闭,但是回调是对CompletionHandler.failed的,但有以下例外:
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) 客户端应该如何关闭套接字,使其不被视为服务器上的错误?
发布于 2013-12-23 19:05:26
关于关闭的文件说它会导致AsynchronousCloseException或ClosedChannelException在另一边。
要导致completed(-1),客户端应该调用shutdownInput。
但是,我会将AsynchronousCloseException和ClosedChannelException视为正常关闭,以及已完成的(-1)。
发布于 2022-04-20 20:45:17
查看堆栈跟踪和实现源,您可能会注意到,异常是由内部sun.nio.ch.UnixAsynchronousSocketChannelImpl#finish()方法引发的,该方法检查挂起的读/写操作。因此,避免此异常的唯一方法是在某个时候防止新的异步read()和write()调用,这应该是应用程序逻辑的一部分。
我已经处理了很多这个异常,在大多数情况下,根本问题在于完成处理程序无条件地“继续侦听”调用:
conn.read(src, attachment, new CompletionHandler<Integer, T>() {
@Override
public void completed(Integer result, T attachment) {
// Some business logic here
// Below is the problem - unconditional read() call
conn.read(src, attachment, this);
}
@Override
public void failed(Throwable t, T attachment) {
// Exception handling
}
});要优雅地关闭连接,不应该有无条件的异步读/写调用。要实现这一点,可能需要发送额外的消息,这意味着不需要新的异步数据,并且关闭连接是安全的。正确的伪代码应该如下所示:
conn.read(src, attachment, new CompletionHandler<Integer, T>() {
@Override
public void completed(Integer result, T attachment) {
// Some business logic here
if(continueListening()) {
conn.read(src, attachment, this);
}
}
// ...
});https://stackoverflow.com/questions/20746091
复制相似问题