编写EchoServer服务端程序
上一章节中,我们已经已经处理了数据并且没有给出任何响应。但是作为一个服务端,通常需要给请求一个响应结果。下面的echo协议例子中无论接收了什么消息均为客户响应了一个消息回去。
与discard仅仅不同的是echo实现了替代discard中的释放代码为接收数据并且打印出接收到的消息到控制台。因此仅仅修改channelRead方法即可。
<pre name="code" class="java">package com.zzj.nio.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.ReferenceCounted;
/**
* 处理一个服务器通道
*/
public class DiscardServerHandler extends SimpleChannelInboundHandler<Object> { // (1)
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
// 当异常发生时,关闭处理器
cause.printStackTrace();
ctx.close();
}
@Override
public void channelRead(ChannelHandlerContext arg0, Object arg1) throws Exception {
ByteBuf msgBuf = (ByteBuf)arg1;
while (msgBuf.isReadable()) { // (1)
System.out.print((char) msgBuf.readByte());
System.out.flush();
}
arg0.writeAndFlush("hello".getBytes());
ReferenceCountUtil.release(msgBuf);
}
/* (non-Javadoc)
* @see io.netty.channel.SimpleChannelInboundHandler#channelRead0(io.netty.channel.ChannelHandlerContext, java.lang.Object)
*/
@Override
protected void channelRead0(ChannelHandlerContext arg0, Object arg1) throws Exception {
// TODO Auto-generated method stub
}
}
其中,1.ChannelHandlerContext对象提供了各种操作来让你触发各种io事件和操作。这里,我们调用write(msg)方法来实现逐个字写接收到的消息。请注意不同于DISCARD的例子我们并没有释放接受到的消息,这是因为当写入的时候Netty已经帮我们释放了。
2.ctx.write(obj)不会使消息马上写出到通道上,它先会被缓存,然后通过ctx.flush出到通道上。另外,也可以调用ctx.writeAndFulsh(msg)。
通过telnet localhost 8888 ,连接服务端后,输入消息,看下控制台有没有打印出来。