public class NIOServer implements Runnable{
private Logger logger=LoggerFactory.getLogger("服务端");
private Selector selector;
private ServerSocketChannel channel;
private int port;
private ByteBuffer buffer;//=ByteBuffer.allocate(1024);
public NIOServer(){
try {
selector=Selector.open();
channel=ServerSocketChannel.open();
channel.configureBlocking(false);
channel.socket().bind(new InetSocketAddress(port),1024);
channel.register(selector, SelectionKey.OP_ACCEPT);
logger.info("服务器启动.."+port);
}catch(IOException e) {
logger.info("服务器启动失败:"+e.toString());
}
}
public NIOServer(int port){
this.port=port;
try {
selector=Selector.open();
channel=ServerSocketChannel.open();
channel.configureBlocking(false);
channel.socket().bind(new InetSocketAddress(port),1024);
channel.register(selector, SelectionKey.OP_ACCEPT);
logger.info("服务器启动.."+port);
}catch(IOException e) {
logger.info("服务器启动失败:"+e.toString());
}
}
private void write(SocketChannel sc) throws IOException {
//buffer.clear();
buffer.put("welcome\n\r".getBytes());
buffer.flip();
while(buffer.hasRemaining()){
sc.write(buffer);
}
sc.register(selector, SelectionKey.OP_READ);
}
private void read(SocketChannel sc) throws IOException {
buffer.clear();
//buffer.flip();
int flag=0,counter=0;
while(true) {
flag=sc.read(buffer);
counter+=flag;
//if(buffer.remaining()==0) break;
logger.info("read result: "+flag+" read counter: "+counter+" buffer remain:"+buffer.remaining());
if(flag==0)break;
if(flag==-1) {
//boolean conn=sc.isConnectionPending();
//if(conn==false) {
sc.close();
throw new IOException("连接故障");
//}
}
//buffer.clear();
}
if(counter>0) {
buffer.flip();
byte[] read=new byte[counter];
//("缓冲区: "+readCounter+" "+read.length);
buffer.get(read,0,read.length);
String expression=new String(read,"utf-8");
logger.info(expression);
buffer.flip();
sc.write(buffer);
}
}
@Override
public void run() {
while(true) {
try {
selector.select(1000);
} catch (IOException e) {
logger.info("select 异常:"+e.toString());
}
Set<SelectionKey> keys=selector.selectedKeys();
if(keys.size()==0) continue;
Iterator<SelectionKey> iteratorKeys=keys.iterator();
while(iteratorKeys.hasNext()) {
SelectionKey key=iteratorKeys.next();
iteratorKeys.remove();
if(key.isReadable()) {
SocketChannel client=(SocketChannel) key.channel();
try {
//ByteBuffer buffer=ByteBuffer.allocate(1024);
// int readCounter=client.read(buffer);
// logger.info("本地端口: "+client.socket().getPort()+" "+readCounter);
// if(readCounter>0) {
// buffer.flip();
// byte[] read=new byte[readCounter];
// buffer.get(read);
// String expression=new String(read,"utf-8");
// logger.info(expression);
// buffer.flip();
// client.write(buffer);
// }
read(client);
}catch(IOException e ) {
logger.info(e.toString());
}
}else if(key.isAcceptable()) {
logger.info("accept: "+LocalDateTime.now().toString());
try {
SocketChannel sChannel=channel.accept();
sChannel.configureBlocking(false);
sChannel.register(selector, SelectionKey.OP_READ);
buffer=ByteBuffer.allocate(1024);
}catch(IOException e) {
logger.info("accept异常: "+e.toString());
}
}
}
}
}
public static void main(String[] args) {
NIOServer server=new NIOServer(7001);
ExecutorService exec=Executors.newCachedThreadPool();
exec.submit(server);
}
}
关键参数:
channel.socket().bind(new InetSocketAddress(host,port),1024); host:本机ip(指定本地ip) port指定使用端口 1024 连接数