欢迎大家讨论,我也是接触时间不长,有问题欢迎大家指正。欢迎转载,转载请注明出处
package com.jjzhk.NIOPractice.MultiSelector;
import java.io.IOException;
public class Server {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
int port = 8008;
new Thread(new ServerReactor(port)).start();
}
}
package com.jjzhk.NIOPractice.MultiSelector;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
public class ServerReactor implements Runnable {
static Logger logger = Logger.getLogger(ServerReactor.class);
private SelectorProvider selectorProvider = SelectorProvider.provider();
private ServerSocketChannel serverSocketChannel;
public ServerReactor(int port) throws IOException {
serverSocketChannel = selectorProvider.openServerSocketChannel(); //ServerSocketChannel.open();
ServerSocket serverSocket = serverSocketChannel.socket();
serverSocket.bind(new InetSocketAddress("localhost", port), 1024);
serverSocketChannel.configureBlocking(false);
logger.debug(String.format("Server : Server Start.----%d", port));
}
public void run() {
try {
new ServerDispatcher(serverSocketChannel, SelectorProvider.provider()).execute();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.jjzhk.NIOPractice.MultiSelector;
import java.io.IOException;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import org.apache.log4j.Logger;
public class ServerDispatcher{
private ServerSocketChannel ssc;
private Selector[] selectors = new Selector[3];
private SelectorProvider selectorProvider;
private final static Logger logger = Logger.getLogger(ServerDispatcher.class);
public ServerDispatcher(ServerSocketChannel ssc, SelectorProvider selectorProvider) throws IOException {
this.ssc = ssc;
this.selectorProvider = selectorProvider;
for (int i = 0; i < 3; i++)
{
selectors[i] = selectorProvider.openSelector();
}
}
public Selector getAcceptSelector()
{
return selectors[0];
}
public Selector getReadSelector()
{
return selectors[1];
}
public Selector getWriteSelector()
{
return selectors[1];
}
public void execute() throws IOException
{
SocketHandler r = new SocketAcceptHandler(this, ssc, getAcceptSelector());
new Thread(r).start();
r = new SocketReadHandler(this, ssc, getReadSelector());
new Thread(r).start();
r = new SocketWriteHandler(this, ssc, getWriteSelector());
new Thread(r).start();
}
}
package com.jjzhk.NIOPractice.MultiSelector;
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.log4j.Logger;
public abstract class SocketHandler implements Runnable{
protected Selector selector;
protected SocketChannel socketChannel = null;
protected ServerSocketChannel serverSocketChannel;
protected ServerDispatcher dispatcher;
protected final static Logger logger = Logger.getLogger(SocketHandler.class);
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();;
public SocketHandler(ServerDispatcher dispatcher, ServerSocketChannel sc, Selector selector) throws IOException{
this.selector = selector;
this.serverSocketChannel = sc;
this.dispatcher = dispatcher;
}
public abstract void runnerExecute(int readyKeyOps) throws IOException;
public final void run()
{
while(true)
{
readWriteLock.readLock().lock();
try {
int keyOps = this.Select();
runnerExecute(keyOps);
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
logger.debug(e.getMessage());
}
finally {
readWriteLock.readLock().unlock();
}
}
}
private int Select() throws IOException
{
int keyOps = this.selector.selectNow();
boolean flag = keyOps > 0;
if (flag)
{
SetreadyKeySet = selector.selectedKeys();
Iterator iterator = readyKeySet.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
keyOps = key.readyOps();
if (keyOps == SelectionKey.OP_READ || keyOps == SelectionKey.OP_WRITE)
{
socketChannel = (SocketChannel)key.channel();
socketChannel.configureBlocking(false);
}
}
}
return keyOps;
}
}
package com.jjzhk.NIOPractice.MultiSelector;
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import org.apache.log4j.Logger;
public class SocketAcceptHandler extends SocketHandler{
private static final Logger logger = Logger.getLogger(SocketAcceptHandler.class);
public SocketAcceptHandler(ServerDispatcher dispatcher, ServerSocketChannel sc, Selector selector)
throws IOException {
super(dispatcher, sc, selector);
serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT, this);
}
@Override
public void runnerExecute(int readyKeyOps) throws IOException {
// TODO Auto-generated method stub
if (readyKeyOps == SelectionKey.OP_ACCEPT)
{
socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
logger.debug("Server accept");
socketChannel.register(dispatcher.getReadSelector(), SelectionKey.OP_READ);
}
}
}
package com.jjzhk.NIOPractice.MultiSelector;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import org.apache.log4j.Logger;
public class SocketReadHandler extends SocketHandler{
static Logger logger = Logger.getLogger(SocketReadHandler.class);
private SelectionKey selectionKey;
private int BLOCK = 4096;
private ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);
public SocketReadHandler(ServerDispatcher dispatcher, ServerSocketChannel sc, Selector selector) throws IOException{
super(dispatcher, sc, selector);
}
@Override
public void runnerExecute(int readyKeyOps) throws IOException {
// TODO Auto-generated method stub
int count = 0;
if (SelectionKey.OP_READ == readyKeyOps)
{
receivebuffer.clear();
count = socketChannel.read(receivebuffer);
if (count > 0) {
logger.debug("Server : Readable.");
receivebuffer.flip();
byte[] bytes = new byte[receivebuffer.remaining()];
receivebuffer.get(bytes);
String body = new String(bytes, "UTF-8");
logger.debug("Server : Receive :" + body);
socketChannel.register(dispatcher.getWriteSelector(), SelectionKey.OP_WRITE);
}
}
}
}
package com.jjzhk.NIOPractice.MultiSelector;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import org.apache.log4j.Logger;
public class SocketWriteHandler extends SocketHandler{
static Logger logger = Logger.getLogger(SocketReadHandler.class);
private int BLOCK = 4096;
private ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);
private static int Index = 1;
public SocketWriteHandler(ServerDispatcher dispatcher, ServerSocketChannel sc, Selector selector) throws IOException{
super(dispatcher, sc, selector);
}
@Override
public void runnerExecute(int readyKeyOps) throws IOException {
// TODO Auto-generated method stub
if (readyKeyOps == SelectionKey.OP_WRITE)
{
logger.debug("Server : Writable.");
String data = String.format("%d", Index);
byte[] req = data.getBytes();
sendbuffer.clear();
logger.debug(String.format("Server : Write %s", data));
sendbuffer = ByteBuffer.allocate(req.length);
sendbuffer.put(req);
sendbuffer.flip();
socketChannel.write(sendbuffer);
Index++;
socketChannel.register(dispatcher.getReadSelector(), SelectionKey.OP_READ);
}
}
}