标签:客户端连接 print 计算 string lazy min import 了解 load
要解决BIO存在的性能问题,本质上是要做到:
1. 让线程不再阻塞
2. 让一个线程能处理多个客户端连接
NIO线程模型,如下图所示
"计算机科学中的一切问题,都可以通过增加中间层来解决",在NIO的设计中被体现了出来。
所以实际上selector, channel, 以及buffer,本质上都是为了解耦
下面以NIO的方式,重写一下EchoServer,直观体验一下JDK的NIO
package org.scaventz.nio.mine; import io.netty.util.CharsetUtil; 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; public class NioEchoServer { public static void main(String[] args) throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.socket().bind(new InetSocketAddress(8080)); // 设置为非阻塞 serverSocketChannel.configureBlocking(false); // 获得一个 Selector 对象 Selector selector = Selector.open(); // 将我们的 serverSocketChannel 注册到 selector上,注册的事件为 ACCEPT事件 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { // 阻塞等待,也可以选择不阻塞 比如select(1000),等待1ms selector.select(); Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> keysIterator = keys.iterator(); while (keysIterator.hasNext()) { SelectionKey key = keysIterator.next(); if (key.isAcceptable()) { System.out.println("连接事件到来"); SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(4096)); keysIterator.remove(); continue; } if (key.isReadable()) { SocketChannel channel = (SocketChannel) key.channel(); ByteBuffer buffer = (ByteBuffer) key.attachment(); channel.read(buffer); System.out.print("收到客户端信息: " + new String(buffer.array(), CharsetUtil.UTF_8)); // 回复客户端 channel.write(buffer); keysIterator.remove(); } } } } }
标签:客户端连接 print 计算 string lazy min import 了解 load
原文地址:https://www.cnblogs.com/heben/p/13179467.html