java nio 断线_NIO 中 检测到 channel 连接断开后的处理方法?

如果检测到连接断开,那么 select 循环就会不断有 read 过来。但我现在对这种情况,有点疑问。

package NonBlocking;

import java.io.IOException;

import java.net.InetSocketAddress;

import java.nio.ByteBuffer;

import java.nio.channels.SelectionKey;

import java.nio.channels.Selector;

import java.nio.channels.SocketChannel;

import java.util.Iterator;

public class TestDisconnectClient {

static SocketChannel socketChannel = null;

static Selector selector = null;

public static void main(String[] args) throws IOException {

socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",8888));

socketChannel.configureBlocking(false);

selector = Selector.open();

socketChannel.register(selector, SelectionKey.OP_READ);

int result = 0; int i = 1;

while((result = selector.select()) > 0) {

System.out.println(String.format("selector %dth loop, ready event number is %d", i++, result));

Iterator iterator = selector.selectedKeys().iterator();

while (iterator.hasNext()) {

SelectionKey sk = iterator.next();

if (sk.isReadable()) {

System.out.println("有数据可读");

SocketChannel canReadChannel = (SocketChannel)sk.channel();

ByteBuffer buf = ByteBuffer.allocate(1024);

try {

while (canReadChannel.read(buf) > 0) {

buf.flip();

System.out.println(new String(buf.array()));

buf.clear();

}

} catch (IOException e) {

//canReadChannel.close();

//sk.cancel();

System.out.println("检测到远程连接断开");

e.printStackTrace();

//continue;

}

}

iterator.remove();

}

}

}

}

如上这种,先运行服务端、客户度,再停止服务端。发现服务端一直有 read 事件过来,循环不停执行。

} catch (IOException e) {

//canReadChannel.close();

//sk.cancel();

System.out.println("检测到远程连接断开");

e.printStackTrace();

continue;

}

}

iterator.remove();

但如果改成如上这种,select 循环检测到一次 read 事件并抛出异常后,循环就退出了。然后整个程序都退出了。这是为啥啊

} catch (IOException e) {

canReadChannel.close();

sk.cancel();

System.out.println("检测到远程连接断开");

e.printStackTrace();

continue;

}

}

iterator.remove();

如果改成如上这种,select 循环检测到一次 read 事件并抛出异常后,下一次循环继续,但会阻塞在 select 那里。

主要想请教下上面三种情况的差异的原因。

还有就是,正确处理连接断开的方法就是:canReadChannel.close();sk.cancel(); 吗

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值