java – NIO Selector Thread,按预期处理通道,但如何确保通道在使用后正确关闭?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – NIO Selector Thread,按预期处理通道,但如何确保通道在使用后正确关闭?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3372字,纯文字阅读大概需要5分钟。
内容图文
所以我在ServerRunnable类中有以下代码:
public class FirmwareServerRunnable implements Runnable {
private static Logger log = Logger.getLogger(FirmwareServerRunnable.class
.getName());
private LinkedTransferQueue<CommunicationState> communicationQueue;
private int serverPort = 48485;
public FirmwareServerRunnable(int port,
LinkedTransferQueue<CommunicationState> communicationQueue) {
serverPort = port;
this.communicationQueue = communicationQueue;
}
private boolean running;
private ServerSocketChannel serverSocketChannel;
@Override
public void run() {
try {
Selector selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
ServerSocket serverSocket = serverSocketChannel.socket();
serverSocket.bind(new InetSocketAddress(serverPort));
log.info("Selector Thread: FirmwareServer Runnable- Listening for connections on port: "
+ serverSocket.getLocalPort());
running = true;
@SuppressWarnings("unused")
SelectionKey serverAcceptKey = serverSocketChannel.register(
selector, SelectionKey.OP_ACCEPT);
while (running) {
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = (SelectionKey) keyIterator.next();
if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
acceptConnection(selector, key);
keyIterator.remove();
} else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
CommunicationState commsState = (CommunicationState) key
.attachment();
if (commsState.getCurrentState() == CommunicationState.STATE_READ) {
readFromSocketChannel(key);
keyIterator.remove();
}
} else if ((key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) {
CommunicationState commsState = (CommunicationState) key
.attachment();
if (commsState.getCurrentState() == CommunicationState.STATE_WRITE) {
writeToSocketChannel(key);
keyIterator.remove();
}
}
}
}
} catch (IOException e) {
log.error(
"Firmware Selector Thread: An IOException occurred",
e);
}
}
我的acceptConnection()方法接受一个连接,并向它添加一个CommunicationState对象(一个状态机),它包含ByteBuffer,当前通道状态,客户端当前在通信过程中等等…
此服务器在进程中间切换通信方法.最初它使用JSON消息与客户端进行通信,但是当它到达某一点时,它开始使用USART protocol commands使用新固件刷新客户端.
完成此过程后,客户端将断开连接并重新启动.这使我的频道处于未知状态.我不确定该频道是否已经关闭.
我怎么检查这个?我是否认为selector.selectedKeys()只返回准备好操作的键?如果是这种情况,我该如何检查未正确关闭的连接?在(运行){}循环中,我可以在此ServerRunnable中执行此操作吗?
我一直在考虑的一个选项是将一个对密钥本身的引用附加到CommunicationState机器上,然后我可以在进程完成后获得对该通道的引用并在那里关闭它.但由于某种原因,我对这个解决方案感到不安,对我来说感觉不对.
如果包含甚至关闭的频道密钥,我可以使用key.isValid()来确认密钥是否需要永久删除?
我很感激你对这个过程的任何想法,我必须忽视一些事情.
编辑:快速测试似乎表明,所选键组中不包含通道键,除非它们已准备好进行三个定义的操作之一
我的测试很糟糕.
解决方法:
已被对等方关闭的连接将导致选择器将您的频道视为可读,当您从中读取时,您将获得-1,因此您应关闭该频道,这将取消其选择键.
编辑
If it’s the case that even closed channel keys are included can I use key.isValid() to confirm that the key needs to be removed permanently?
如果您关闭了频道,其键将被取消,因此您下次在选定键集中将看不到它.如果对等方关闭了连接,请参见上文.
内容总结
以上是互联网集市为您收集整理的java – NIO Selector Thread,按预期处理通道,但如何确保通道在使用后正确关闭?全部内容,希望文章能够帮你解决java – NIO Selector Thread,按预期处理通道,但如何确保通道在使用后正确关闭?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。