📄 reactor.java
字号:
package net;
import java.nio.channels.*;
import java.nio.channels.ServerSocketChannel;
import java.net.*;
import java.util.*;
import java.io.*;
/**
* 反应器<br>
* 通过构造方法产生一个反应器(选择器),构造Unix系统常用的网络通信select架构<br>
* 通过KVM内部的select结构,对网络事件做出反应,比如连接,读,写等。
*
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2006</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
public class Reactor
implements Runnable {
private final Selector selector;
private final ServerSocketChannel serverSocketChannel;
private final NetListener processor;
private boolean shutdown = false;
/**
* 构造方法
*
* @param port int
* @param processor AcceptionListener
* @throws IOException
*/
public Reactor(int port, NetListener processor) throws IOException {
this.processor = processor;
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
InetSocketAddress isa = new InetSocketAddress(port);
serverSocketChannel.socket().bind(isa); //绑定
serverSocketChannel.configureBlocking(false); //非阻塞
SelectionKey sk = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); //注册监听选择器
sk.attach(new Acceptor());
}
public void shutdown() {
shutdown = true;
}
/**
* 选择器线程,此线程会对所有连接的读写进行响应,通过回调Handle和Acceptor的run()方法实现。
*/
public void run() {
try {
while (!shutdown) {
int num = selector.select();
//select方法可能返回为0
//所以加上此判断
if (num > 0) {
Set selected = selector.selectedKeys();
Iterator it = selected.iterator();
while (it.hasNext()) {
dispatch( (SelectionKey) it.next());
}
selected.clear();
}
synchronized (this) {
try {
wait(100);
}
catch (InterruptedException ex) {
}
}
} //end while
}
catch (IOException e) {
}
}
/**
* 任务分发
* @param k SelectionKey
*/
private void dispatch(SelectionKey k) {
Runnable r = (Runnable) k.attachment();
if (r != null) {
r.run();
}
}
/**
* 接收者,当监听到一个连接请求时,产生一个接收者
*
* 这个任务产生一个Handle,Handle实际上是一个连接的管理器,负责对一个客户的所有通信进行管理
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2006</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
class Acceptor
implements Runnable {
/**
* 反应器回调接口
*/
public void run() {
try {
System.out.println("Acceptor:" + this);
SocketChannel sc = serverSocketChannel.accept();
sc.configureBlocking(false);
if (sc != null) {
//accpet后将key的attach转到handle上面
Handler h = new Handler(selector, sc);
//如果网络监听器不为空,则执行定制操作
if (processor != null) {
processor.onAccept(h);
}
}
}
catch (IOException e) {
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -