NIO跑死的有关问题,求看代码哪里有有关问题

NIO跑死的问题,求看代码哪里有问题
本帖最后由 o0caicaihua 于 2014-06-12 09:57:51 编辑
最近NIO的服务端程序挂个一两天总是跑死了,NIO是非阻塞的我想应该也不会阻塞。最后发现一个地方的代码有点问题。

每次都会出现这样的问题跑死;

NIO跑死的有关问题,求看代码哪里有有关问题

这是我自己catch打印的远程主机断开连接。

每一个catch里面报错都是:
java.io.IOException: 远程主机强迫关闭了一个现有的连接。
at sun.nio.ch.SocketDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(Unknown Source)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
at sun.nio.ch.IOUtil.read(Unknown Source)
at sun.nio.ch.SocketChannelImpl.read(Unknown Source)
at com.donen.services.TCPProtocolImpl.handleRead(TCPProtocolImpl.java:43)
at com.donen.services.TCPServer.open(TCPServer.java:70)
at com.donen.services.TCPServer.run(TCPServer.java:96)


发现只要有一个设备突然断网之类的断开连接就会一直循环报这个错误。现在有很多个设备,如果设备掉线的越来越多,很多歌这样的循环一直显示可能就会是我程序跑死的原因。

但是代码以前就写了,如果设备掉线不能处理就丢掉啊,但是为何没有用

处理完了会移除keyIter.remove();  如果发现上面那种IOException catch里面也会移除keyIter.remove();
为何出现了上面的异常,catch里面也移除了,但是还是一直跑循环 打印那个错误?


// 反复循环,等待IO
while (true) {
// 等待某信道就绪(或超时)
if (selector.select(TimeOut) == 0) {
System.out.print("waiting.");
continue;
}

// 取得迭代器.selectedKeys()中包含了每个准备好某一I/O操作的信道的SelectionKey
Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();

while (keyIter.hasNext()) {
SelectionKey key = keyIter.next();
try {
if (key.isAcceptable()) {
// 有客户端连接请求时
protocol.handleAccept(key);
}

if (key.isReadable()) {
// 从客户端读取数据
protocol.handleRead(key);
}

if (key.isValid() && key.isWritable()) {
// 客户端可写时
protocol.handleWrite(key, null);
}
} catch (IOException ex) {
System.out.println("----远程主机断开连接----");
// 出现IO异常(如客户端断开连接)时移除处理过的键
                                        //下面两句使用与否都一样,反正catch下面也要remove();再循环
//keyIter.remove();
//continue;
}
// 移除处理过的键
keyIter.remove();
}
}

------解决方案--------------------
 catch (IOException ex) {}里面加一句SelectionKey.cancel()
按道理 (bytesRead == -1)  里面应该也加一句。
不再用的通道都要cancel()