package com.net.test;
import java.io.IOException;
import java.net.InetSocketAddress;
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 com.net.tcp.DataCache;
import com.net.tcp.DataPack;
import com.net.tcp.StreamObjectManager;
/**
*
* nio通信服務端
*
*/
public class NIOServer {
private ServerSocketChannel serverSokcetChannel;
private Selector selector;
public NIOServer(int port) throws Exception{
serverSokcetChannel = ServerSocketChannel.open();
serverSokcetChannel.configureBlocking(false);
serverSokcetChannel.socket().bind(new InetSocketAddress(port));
selector = Selector.open();
serverSokcetChannel.register(selector, SelectionKey.OP_ACCEPT);
listen();
}
public void listen(){
Set<SelectionKey> keys = null;
Iterator<SelectionKey> keyIt = null;
SelectionKey key = null;
while(true){
try {
selector.select();
keys = selector.selectedKeys();
keyIt = keys.iterator();
while(keyIt.hasNext()){
key = keyIt.next();
keyIt.remove();
dealKey(key);
}
} catch (Exception e) {
e.printStackTrace();
if(key != null)
closeChannel((SocketChannel)key.channel());
}
}
}
public void dealKey(SelectionKey key) throws Exception{
if(key.isAcceptable()){
ServerSocketChannel serverChannel = (ServerSocketChannel)key.channel();
SocketChannel channel = serverChannel.accept();
channel.configureBlocking(false);
DataCache[] caches = {new DataCache(1024), new DataCache(0)};
channel.register(selector, SelectionKey.OP_READ, caches);
}else if(key.isReadable()){
SocketChannel channel = (SocketChannel)key.channel();
DataCache[] cache = (DataCache[])key.attachment();
if(cache[0].read(channel) > 0){
DataPack pack = null;
boolean sign = false;
while((pack = cache[0].poll()) != null){
cache[1].push(pack);
sign = true;
}
if(sign){
key.interestOps(SelectionKey.OP_WRITE);
}
}else{
closeChannel(channel);
}
// ByteBuffer buffer = ByteBuffer.allocate(1024);
// if(channel.read(buffer) > 0){
// buffer.flip();
// int size = buffer.getInt();
// byte[] bytes = new byte[size];
// buffer.get(bytes);
// DataPack pack = new DataPack();
// pack.getContent().putBytes(bytes);
// pack.filp();
// Object object = pack.getObject();
// key.interestOps(SelectionKey.OP_WRITE);
// key.attach(object);
// }else{
// closeChannel(channel);
// }
}else if(key.isWritable()){
SocketChannel channel = (SocketChannel)key.channel();
DataCache[] cache = (DataCache[])key.attachment();
if(cache[1].write(channel)){
key.interestOps(SelectionKey.OP_READ);
}
// DataPack pack = new DataPack();
// pack.putObject(key.attachment(), DataType.TYPE_OBJECT);
// pack.filp();
// channel.write(pack.getHead().getContent());
// ByteBuffer buffer = pack.getContent().current(false);
// while(buffer != null){
// channel.write(buffer);
// buffer = pack.getContent().next(false);
// }
// key.interestOps(SelectionKey.OP_READ);
}
}
public void closeChannel(SocketChannel channel){
if(channel != null){
SelectionKey key = channel.keyFor(selector);
if(key != null){
key.cancel();
}
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) throws Exception{
StreamObjectManager.init("com.net.test.*");
new NIOServer(2345);
}
}