繼承一個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