public class NIOServer {
private Selector selector;
/***
* 获取serversocket通道,并对该通道做一些初始化的工作
*
* @param port
* @throws IOException
*/
private void initServer(int port) throws IOException {
// 获取一个serversocket通道
ServerSocketChannel channel = ServerSocketChannel.open();
// 设置通道为非阻塞
channel.configureBlocking(false);
// 在通道中获取服务端的ServerSocket
ServerSocket serverSocket=channel.socket();
//服务端的ServerSocket绑定到port端口
serverSocket.bind(new InetSocketAddress(port));
// 获得一个通道管理器
this.selector = selector.open();
// 讲通道管理器和该通道绑定,并为改通道注册SelectionKey.OP_ACCEPT事件
// 注册该事件后,当该事件到达时,this.selector.select()会返回
// 如果该事件没有到达this.selector.select()会一直阻塞
channel.register(selector, SelectionKey.OP_ACCEPT);
}
public void listen() throws IOException {
System.out.println("服务器启动成功");
// 轮询访问selector
while (true) {
// 当注册的事件到达时,方法返回,否则该方法会一直阻塞
selector.select();
// 获取selector
Iterator<SelectionKey> ite = this.selector.selectedKeys()
.iterator();
while (ite.hasNext()) {
SelectionKey key = ite.next();
// 删除已选的key,以防止重复处理
ite.remove();
handler(key);
}
}
}
/***
* 处理请求
* @param key
* @throws IOException
*/
private void handler(SelectionKey key) throws IOException {
//客服端请求连接事件
if(key.isAcceptable()){
handlerAccept(key);
}else if (key.isReadable()) {
// 获得了可读的事件
handelerRead(key);
}
}
/**
* 处理连接请求
* @param key
* @throws IOException
*/
private void handlerAccept(SelectionKey key) throws IOException {
// 获取服务端的serverSocket
ServerSocketChannel server = (ServerSocketChannel) key.channel();
//从服务端的serverSocket中获取连接的客户端socket的通道
SocketChannel clent =server.accept();
//客户端通道设置成非阻塞
clent.configureBlocking(false);
//在这里可以给客户端发送消息
System.out.println("新的客户端连接");
//在和客户端连接成功后,为了可以接收到客户端的消息,需要给通道设置读的权限
clent.register(this.selector,SelectionKey.OP_READ);
}
/***
* 处理读的事件
* @param key
* @throws IOException
*/
private void handelerRead(SelectionKey key) throws IOException {
//服务器可读消息:得到了事件发生的socket通道
//获取到客户端socket通道
SocketChannel socketChannel=(SocketChannel) key.channel();
ByteBuffer buffer=ByteBuffer.allocate(1024);
//把数据读到缓存区中去
int read=socketChannel.read(buffer);
if(read>0){
byte[] data=buffer.array();
String message=new String(data).trim();
System.out.println("服务端收到到客户端的消息="+message);
//回写信息
ByteBuffer writeMessage=ByteBuffer.wrap("好多".getBytes());
socketChannel.write(writeMessage);
}else{
System.out.println("客户端关闭");
key.cancel();
}
}
/**
* 启动服务端测试
*
* @throws IOException
*/
public static void main(String[] args) throws IOException {
NIOServer server = new NIOServer();
server.initServer(8000);
server.listen();
}
}
在win dom中输入 telnet 127.0.0.1 8000
服务端输出。
服务端发送,客户端发送接收等代码类是,就不写的了。