第一节说的例子太简单,实际状况当中咱们要对消息进行处理。如今咱们来写一个时间服务器。时间服务器的TimeServer文件和第一节里面差很少,改几个类名就能够了,咱们只要看下时间服务器的handler。在连接创建之后,服务器向客户端发送系统时间,这个时间是32比特的整数,发送完毕以后就关闭服务器,而不用一直保持读取状态,因此在这里咱们在Handler里面不可以使用channelRead()方法,而是使用channelActive()方法。java
package com.hengzecn.NettyClient; import java.util.Date; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; public class TimeClientHandler extends ChannelInboundHandlerAdapter { private ByteBuf buf; @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { buf = ctx.alloc().buffer(4); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { buf.release(); buf = null; } @Override public void channelRead(ChannelHandlerContext ctx, Object msg){ ByteBuf m = (ByteBuf) msg; buf.writeBytes(m); m.release(); if(buf.readableBytes() >= 4){ long currentTimeMillis = (buf.readUnsignedInt() - 2208988800L) * 1000L; System.out.println(new Date(currentTimeMillis)); ctx.close(); } // try { // long currentTimeMillis = (m.readUnsignedInt() - 2208988800L) * 1000L; // System.out.println(new Date(currentTimeMillis)); // ctx.close(); // } finally{ // m.release(); // } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){ cause.printStackTrace(); ctx.close(); } }
咱们用Netty来写个客户端测试下:bootstrap
package com.hengzecn.NettyClient; import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; public class TimeClient { public static void main(String[] args) throws Exception{ String host = "127.0.0.1"; int port = 8080; EventLoopGroup workerGroup = new NioEventLoopGroup(); try{ Bootstrap b = new Bootstrap(); b.group(workerGroup); b.channel(NioSocketChannel.class); b.option(ChannelOption.SO_KEEPALIVE, true); b.handler(new ChannelInitializer<SocketChannel>(){ @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new TimeClientHandler()); } }); ChannelFuture f = b.connect(host, port).sync(); f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); } } }
客户端的Handler使用channelRead来读取服务器端发来的信息:服务器
package com.hengzecn.NettyClient; import java.util.Date; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; public class TimeClientHandler extends ChannelInboundHandlerAdapter { private ByteBuf buf; @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { buf = ctx.alloc().buffer(4); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { buf.release(); buf = null; } @Override public void channelRead(ChannelHandlerContext ctx, Object msg){ ByteBuf m = (ByteBuf) msg; buf.writeBytes(m); m.release(); if(buf.readableBytes() >= 4){ long currentTimeMillis = (buf.readUnsignedInt() - 2208988800L) * 1000L; System.out.println(new Date(currentTimeMillis)); ctx.close(); } // try { // long currentTimeMillis = (m.readUnsignedInt() - 2208988800L) * 1000L; // System.out.println(new Date(currentTimeMillis)); // ctx.close(); // } finally{ // m.release(); // } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){ cause.printStackTrace(); ctx.close(); } }
运行客户端,成功收到了服务器发来的时间信息,收到信息后服务就关闭了,以下图所示:异步