标签:last 它的 code register res ini 业务 数据流 等等
一。用netty创建server
package com.cw.demo.netty.server; import com.cw.demo.netty.server.channelhandler.EchoServerHandler; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; 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.nio.NioServerSocketChannel; /** * @author chenwei * Created by chenwei01 on 2017/4/24. * 1.创建ServerBootstrap实例来引导绑定和启动服务器 * 2.创建NioEventLoopGroup对象来处理事件,如接受新连接、接收数据、写数据等等 * 3.指定InetSocketAddress,服务器监听此端口 * 4.设置childHandler执行所有的连接请求 * 5.都设置完毕了,最后调用ServerBootstrap.bind() 方法来绑定服务器 */ public class EchoServer { private int port; public EchoServer(int port){ this.port=port; } public void start() throws Exception{ //因为使用NIO,指定NioEventLoopGroup来接受和处理新连接 EventLoopGroup group = new NioEventLoopGroup(); //创建bootstrap来启动服务器 ServerBootstrap boot = new ServerBootstrap(); boot.group(group). //指定通道类型为NioServerSocketChannel channel(NioServerSocketChannel.class). localAddress(port). //调用childHandler用来指定连接后调用的ChannelHandler childHandler(new ChannelInitializer<Channel>() { //这个方法传ChannelInitializer类型的参数,ChannelInitializer是个抽象类,所以需要实现initChannel方法,这个方法就是用来设置ChannelHandler @Override protected void initChannel(Channel channel) throws Exception { channel.pipeline().addLast(new EchoServerHandler()); } }); ChannelFuture future=boot.bind().sync(); System.out.println( EchoServer.class.getName()+" started and listen on "+future.channel().localAddress()); future.channel().closeFuture().sync(); } public static void main(String[] args) { EchoServer server=new EchoServer(20000); try { server.start(); } catch (Exception e) { e.printStackTrace(); } } }
创建 ChannelHandler,实际上 ChannelHandler 处理实际业务的主要代码
package com.cw.demo.netty.server.channelhandler; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.ReferenceCountUtil; import java.nio.charset.Charset; /** * Netty中有两个方向的数据流,上图显示的入站(ChannelInboundHandler)和出站(ChannelOutboundHandler)之间有一个明显的区别: * 若数据是从用户应用程序到远程主机则是“出站(outbound)”, * 相反若数据时从远程主机到用户应用程序则是“入站(inbound)”。 * 为了使数据从一端到达另一端,一个或多个ChannelHandler将以某种方式操作数据。 * 这些ChannelHandler会在程序的“引导”阶段被添加ChannelPipeline中,并且被添加的顺序将决定处理数据的顺序。 * ChannelPipeline的作用我们可以理解为用来管理ChannelHandler的一个容器,每个ChannelHandler处理各自的数据(例如入站数据只能由ChannelInboundHandler处理), * 处理完成后将转换的数据放到ChannelPipeline中交给下一个ChannelHandler继续处理,直到最后一个ChannelHandler处理完成。 */ /** * @author chenwei * Created by chenwei01 on 2017/4/25. * Netty使用多个Channel Handler来对事件处理的分离,因为可以很容的添加、更新、删除业务逻辑处理handler * 它的每个方法都可以被重写,它的所有的方法中只有channelRead方法是必须要重写的。 */ public class EchoServerHandler extends ChannelInboundHandlerAdapter { //重写该方法,该方法会被调用用来接收数据 @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("Server reveived: " + ((ByteBuf) msg).toString(Charset.forName("UTF-8"))); Channel channel = ctx.channel(); channel.writeAndFlush(Unpooled.buffer().writeBytes("我收到了".getBytes("UTF-8"))); ReferenceCountUtil.release(msg); } @Override public void channelRegistered(ChannelHandlerContext ctx) throws Exception { Channel channel = ctx.channel(); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } }
二。客户端测试
客户端代码与服务端代码大致类似,不过是启动类用了 Bootstrap 而不是 ServerBootstrap
或者最简单的,用telnet 来测试 刚才写的nettyServer
标签:last 它的 code register res ini 业务 数据流 等等
原文地址:https://www.cnblogs.com/manmanrenshenglu/p/9013346.html