86 lines
2.7 KiB
Java
86 lines
2.7 KiB
Java
|
package com.thinker.common.nio;
|
|||
|
|
|||
|
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;
|
|||
|
|
|||
|
/**
|
|||
|
* nio nio different from bio nio
|
|||
|
*
|
|||
|
* */
|
|||
|
public class NioServer{
|
|||
|
|
|||
|
private Selector selector;
|
|||
|
/**
|
|||
|
*
|
|||
|
* @param port 监听端口
|
|||
|
* 初始化服务器
|
|||
|
*
|
|||
|
* */
|
|||
|
private NioServer init(int port) throws IOException{
|
|||
|
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
|
|||
|
serverSocketChannel.configureBlocking(false);
|
|||
|
serverSocketChannel.bind(new InetSocketAddress(port));
|
|||
|
selector = Selector.open();
|
|||
|
//将通道管理器与通道绑定,并为该通道注册SelectionKey.OP_ACCEPT事件
|
|||
|
//只有当该事件到达时Select.select()会返回,否则一直阻塞。
|
|||
|
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
|
|||
|
return this;
|
|||
|
}
|
|||
|
public void listen() throws IOException{
|
|||
|
System.out.println("service starting.....");
|
|||
|
while(true){
|
|||
|
//当有注册事件到达时方法返回,否则阻塞
|
|||
|
selector.select();
|
|||
|
//获取selector中的迭代器,选中项为注册的事件
|
|||
|
Iterator<SelectionKey> ite = selector.selectedKeys().iterator();
|
|||
|
while(ite.hasNext()){
|
|||
|
SelectionKey key = ite.next();
|
|||
|
//删除已选key,防止重复处理
|
|||
|
ite.remove();
|
|||
|
//客户端连接事件
|
|||
|
if(key.isAcceptable()){
|
|||
|
ServerSocketChannel server = (ServerSocketChannel)key.channel();
|
|||
|
//获取客户端连接通道
|
|||
|
SocketChannel channel = server.accept();
|
|||
|
channel.configureBlocking(false);
|
|||
|
channel.write(ByteBuffer.wrap(new String("send to client").getBytes()));
|
|||
|
channel.register(selector, SelectionKey.OP_READ);
|
|||
|
System.out.println("client connect");
|
|||
|
}else if(key.isReadable()){//有可读数据事件
|
|||
|
//获取客户端传输数据可读消息通道。
|
|||
|
SocketChannel channel = (SocketChannel)key.channel();
|
|||
|
//创建读取数据缓存器
|
|||
|
ByteBuffer buffer = ByteBuffer.allocate(1024);
|
|||
|
int read = channel.read(buffer);
|
|||
|
byte[] data = buffer.array();
|
|||
|
String message = new String(data);
|
|||
|
|
|||
|
System.out.println("receive message from client, size:"+buffer.position()+"\tmessage:"+message);
|
|||
|
try{
|
|||
|
Thread.sleep(1000);
|
|||
|
}catch(InterruptedException e){
|
|||
|
e.printStackTrace();
|
|||
|
break;
|
|||
|
}
|
|||
|
ByteBuffer out = ByteBuffer.wrap(new String("hello world").getBytes());
|
|||
|
channel.write(out);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
public static void main(String[] args) {
|
|||
|
try{
|
|||
|
new NioServer().init(1994).listen();
|
|||
|
}catch(IOException e){
|
|||
|
e.printStackTrace();
|
|||
|
System.exit(0);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|