第一个Netty程序
netty就是一个高性能的NIO框架,用于java网络编程。下面说说思路:
服务端:
开启通道、设置网络通信方式、设置端口、设置接收请求的handler、绑定通道、最后关闭
客户端:
开启通道、设置网络通信方式、设置服务器ip和端口、设置处理数据的handler、连接服务器、最后关闭。
pom.xml引用如下:
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.28.Final</version> </dependency>
服务端总共两个类,EchoServer.java和EchoServerHandler.java。
EchoServer.java
package cn.enjoyedu.ch02.echo; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import java.net.InetSocketAddress; /** * * 创建日期:2018/08/25 * 类说明: */ public class EchoServer { private final int port; public EchoServer(int port) { this.port = port; } public static void main(String[] args) throws InterruptedException { int port = 9999; EchoServer echoServer = new EchoServer(port); System.out.println("服务器即将启动"); echoServer.start(); System.out.println("服务器关闭"); } public void start() throws InterruptedException { final EchoServerHandler serverHandler = new EchoServerHandler(); /*线程组*/ EventLoopGroup group = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap();/*服务端启动必备*/ b.group(group) /*指明使用NIO进行网络通讯*/ .channel(NioServerSocketChannel.class) /*指明服务器监听端口*/ .localAddress(new InetSocketAddress(port)) /*接收到连接请求,新启一个socket通信,也就是channel,每个channel * 有自己的事件的handler*/ .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new EchoServerHandler()); } }); ChannelFuture f = b.bind().sync();/*绑定到端口,阻塞等待直到连接完成*/ /*阻塞,直到channel关闭*/ f.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync(); } } }
EchoServerHandler.java
package cn.enjoyedu.ch02.echo; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.CharsetUtil; /** * 创建日期:2018/08/25 * 类说明:自己的业务处理 */ /*指明我这个handler可以在多个channel之间共享,意味这个实现必须线程安全的。*/ @ChannelHandler.Sharable public class EchoServerHandler extends ChannelInboundHandlerAdapter { /*** 服务端读取到网络数据后的处理*/ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf in = (ByteBuf)msg;/*netty实现的缓冲区*/ System.out.println("Server Accept:"+in.toString(CharsetUtil.UTF_8)); ctx.write(in); } /*** 服务端读取完成网络数据后的处理*/ @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)/*flush掉所有的数据*/ .addListener(ChannelFutureListener.CLOSE);/*当flush完成后,关闭连接*/ } /*** 发生异常后的处理*/ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } }
客户端总共两个类,EchoClient.java和EchoClientHandler.java
EchoClient.java
package cn.enjoyedu.ch02.echo; import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import java.net.InetSocketAddress; /** * 创建日期:2018/08/26 * 类说明:netty的客户端 */ public class EchoClient { private final int port; private final String host; public EchoClient(int port, String host) { this.port = port; this.host = host; } public void start() throws InterruptedException { EventLoopGroup group = new NioEventLoopGroup();/*线程组*/ try { Bootstrap b = new Bootstrap();/*客户端启动必备*/ b.group(group) .channel(NioSocketChannel.class)/*指明使用NIO进行网络通讯*/ .remoteAddress(new InetSocketAddress(host,port))/*配置远程服务器的地址*/ .handler(new EchoClientHandler()); ChannelFuture f = b.connect().sync();/*连接到远程节点,阻塞等待直到连接完成*/ /*阻塞,直到channel关闭*/ f.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync(); } } public static void main(String[] args) throws InterruptedException { new EchoClient(9999,"127.0.0.1").start(); } }
EchoClientHandler.java
package cn.enjoyedu.ch02.echo; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.CharsetUtil; /** * 创建日期:2018/08/26 * 类说明: */ public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> { /*客户端读取到数据后干什么*/ @Override protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { System.out.println("Client accetp:"+msg.toString(CharsetUtil.UTF_8)); } /*客户端被通知channel活跃以后,做事*/ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { //往服务器写数据 ctx.writeAndFlush(Unpooled.copiedBuffer("Hello,Netty", CharsetUtil.UTF_8)); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } }
代码里面也有具体的注释。