继承一个SimpleChannelInboundHandler来实现咱们的Client,咱们须要重写其中的三个方法:java
package NettyDemo.echo.handler; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.ChannelHandler.Sharable; import io.netty.util.CharsetUtil; @Sharable public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> { /** *此方法会在链接到服务器后被调用 * */ public void channelActive(ChannelHandlerContext ctx) { ctx.write(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8)); } /** *此方法会在接收到服务器数据后调用 * */ public void channelRead0(ChannelHandlerContext ctx, ByteBuf in) { System.out.println("Client received: " + ByteBufUtil.hexDump( in.readBytes(in.readableBytes()))); } /** *捕捉到异常 * */ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } }
其中须要注意的是 channelRead0()方法,此方法接收到的多是一些数据片断,好比服务器发送了5个字节数据,Client端不能保证一次所有收到,好比第一次收到3个字节,第二次收到2个字节。咱们可能还会关心收到这些片断的顺序是否可发送顺序一致,这要看具体是什么协议,好比基于TCP协议的字节流是能保证顺序的。服务器
还有一点,在Client端咱们的业务Handler继承的是SimpleChannelInboundHandler,而在服务器端继承的是ChannelInboundHandlerAdapter,那么这两个有什么区别呢?最主要的区别就是SimpleChannelInboundHandler在接收到数据后会自动release掉数据占用的Bytebuffer资源(自动调用Bytebuffer.release())。而为什么服务器端不能用呢,由于咱们想让服务器把客户端请求的数据发送回去,而服务器端有可能在channelRead方法返回前尚未写完数据,所以不能让它自动release。.net