package com.net.test;
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.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import com.net.tcp.DataPack;
import com.net.tcp.DataType;
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);
channel.register(selector, SelectionKey.OP_READ);
}else if(key.isReadable()){
SocketChannel channel = (SocketChannel)key.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();
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);
}
}