jdk nio 服务器
引言
在学习 netty 之前咱们须要理解 nio,于是我就想分享一下如何用 jdk nio 写一个服务
流程
步骤 1:关上一个服务管道(Channel),并设置非阻塞模式
步骤 2:创立服务
步骤 3:关上一个多路复用器,并注册到 Channel,对 ACCEPT 事件感兴趣
步骤 4:轮询抉择多路复用器,针对不同的复用器进行相干的操作(读、写)
public class NoUseNettyNio {public void serve(int port) throws IOException {
// 关上一个 ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 设置一个 serverSocketChannel 为不阻塞模式,即 nio
serverSocketChannel.configureBlocking(false);
// 通过 serverSocketChannel 获取 serverSocket
ServerSocket serverSocket = serverSocketChannel.socket();
// 创立一个 server 的网卡地址对象
InetSocketAddress address = new InetSocketAddress(port);
// 为 serverSocket 绑定网卡地址
serverSocket.bind(address);
// 关上一个 selector(多路复用器)Selector selector = Selector.open();
// 将多路复用器注册到 serverSocketChannel(管道)上
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
// 创立一个 byteBuffer
ByteBuffer buffer = ByteBuffer.wrap(("HTTP/1.1 200 OK\r\n" +
"Content-Type: text/html;charset=UTF-8\r\n").getBytes(StandardCharsets.UTF_8));
for (; ;) {
try {
// 抉择一个通道,此办法是阻塞的,在有一个通道、线程中断或 Selector 的唤醒时,返回
selector.select();} catch (IOException e) {e.printStackTrace();
break;
}
// 获取的一个 selectKey 汇合,该汇合只能删除不能增加,Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {SelectionKey key = iterator.next();
iterator.remove();
try {if (key.isAcceptable()) {ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel client = server.accept();
client.configureBlocking(false);
client.register(selector,SelectionKey.OP_READ|SelectionKey.OP_WRITE,buffer.duplicate());
System.out.println("Accepted connection from"+client);
}
if(key.isWritable()) {SocketChannel client = (SocketChannel) key.channel();
ByteBuffer attachment = (ByteBuffer) key.attachment();
while (buffer.hasRemaining()) {System.out.println(attachment.toString());
if(client.write(attachment) == 0) {break;}
}
client.close();}
} catch (IOException e) {key.channel();
try {key.channel().close();} catch (IOException ex) { }
e.printStackTrace();}
}
}
}
public static void main(String[] args) throws IOException {NoUseNettyNio noUseNettyNio = new NoUseNettyNio();
noUseNettyNio.serve(8910);
}
}