/**
* 轮询监听selector刚兴趣的事件.
*/
@Override
public void run() {
try {
System.out.println("第" + index + "个客户端启动!");
// 先尝试异步连接服务器, 如果连接成功,则只需要把channel注册到selector的READ事件,
// 读取服务器返回的结果. 如果不成功(客户端已经向服务器发送了sync包,但是服务器没有返回ack包, 物理链路还没建立成功)
// 则把该channel注册到selector的CONNECT事件, 等待服务器返回的ack包.
if (channel.connect(new InetSocketAddress(8080))) {
channel.register(selector, SelectionKey.OP_READ);
doWrite(channel, TIME_ORDER);
} else {
channel.register(selector, SelectionKey.OP_CONNECT);
}
while (!stop) {
selector.select(1000);
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
SocketChannel sc = (SocketChannel) key.channel();
iterator.remove();
if (key.isValid()) {
if (key.isReadable()) { // 监听到可读事件, 读取服务器返回的处理结果.
ByteBuffer buff = ByteBuffer.allocate(1024);
int size = sc.read(buff);
if (size > 0) {
byte[] b = new byte[size];
buff.flip();
buff.get(b);
System.out.println("第" + index + "个客户端获取服务器返回时间:" + new String(b));
stop = true;
} else if (size < 0) {
sc.close();
key.cancel();
} else {
;
}
}
if (key.isConnectable()) { //监听到服务器返回了ack包, 准备完成连接的建立
if (sc.finishConnect()) { // 调用此方法完成物理链路连接的建立
sc.register(selector, SelectionKey.OP_READ); // 建立连接之后注册监听READ事件
doWrite(sc, TIME_ORDER);
} else {
System.exit(1); //否则,程序退出
}
}
}
}
}
if (selector != null) {
selector.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Java IO多路复用技术简介(3)
内容版权声明:除非注明,否则皆为本站原创文章。
转载注明出处:https://www.heiqu.com/8d4ecd5ba8b62a53f2b9ad15127ee7f5.html