Netty定义:Netty 是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能服务器和客户端。
通常Netty内部封装了JDK的NIO。
使用Netty封装NIO而不用NIO的原因
- Netty 自带的拆包解包,异常检测等机制让你从NIO的繁重细节中脱离出来,让你只需要关心业务逻辑
- Netty 解决了 JDK 的很多包括空轮询在内的 Bug
- Netty 底层对线程,selector 做了很多细小的优化,精心设计的 reactor 线程模型做到非常高效的并发处理
- 自带各种协议栈让你处理任何一种通用协议都几乎不用亲自动手
那么通过代码实现Netty。
实现Netty ,需要在pom.xml中加入依赖
io.netty netty-all 4.1.6.Final
1、首先是服务端。其中实现了服务端的启动,端口的绑定,接收新连接,打印数据
public class NIOServer { public static void main(String[] args) throws IOException { Selector serverSelector = Selector.open(); Selector clientSelector = Selector.open(); new Thread(() -> { try { // 对应IO编程中服务端启动 ServerSocketChannel listenerChannel = ServerSocketChannel.open(); listenerChannel.socket().bind(new InetSocketAddress(8000)); listenerChannel.configureBlocking(false); listenerChannel.register(serverSelector, SelectionKey.OP_ACCEPT); while (true) { // 监测是否有新的连接,这里的1指的是阻塞的时间为 1ms if (serverSelector.select(1) > 0) { Setset = serverSelector.selectedKeys(); Iterator keyIterator = set.iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (key.isAcceptable()) { try { // (1) 每来一个新连接,不需要创建一个线程,而是直接注册到clientSelector SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept(); clientChannel.configureBlocking(false); clientChannel.register(clientSelector, SelectionKey.OP_READ); } finally { keyIterator.remove(); } } } } } } catch (IOException ignored) { } }).start(); }}
server端中boss对应IOServer.java中创建新连接的部分,worker对应IOServer.java中的负责读取数据的线程,主要用于读取数据以及业务逻辑处理。
2、然后是客户端的实现
public class NettyClient { public static void main(String[] args) throws InterruptedException{ Bootstrap bootstrap = new Bootstrap(); NioEventLoopGroup group = new NioEventLoopGroup(); bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer() { @Override protected void initChannel(Channel channel) throws Exception { channel.pipeline().addLast(new StringEncoder()); } }); Channel channel = bootstrap.connect("127.0.0.1",8000).channel(); while(true){ channel.writeAndFlush(new Date()+"Hello World"); Thread.sleep(2000); } }}
此段实现了,客户端的连接