Netty实践-Echo服务器

到目前为止,我们一直在学习编写服务器处理数据但没有做任何响应处理。 然而,服务器通常应该响应请求。现在就来学习如何通过实现ECHO协议向客户端写入响应消息,将接收到任何数据发送回客户端。

与上一个示例中实现的”丢弃”(discard )服务器的唯一区别是,它将接收到的数据发送回来,而不是将接收的数据打印到控制台。因此,再次修改channelRead()方法就足够了:

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ctx.write(msg); // (1)
        ctx.flush(); // (2)
    }
  1. ChannelHandlerContext对象提供了各种操作,使您能够触发各种I/O事件和操作。 这里,我们调用write(Object)来逐字写入接收到的消息。请注意,不像我们在DISCARD示例中,这里没有释放收到的消息。这是因为Netty在写出来的时候就自动释放它了。

  2. ctx.write(Object)并不会将消息写入线路。 它在内部缓冲,然后可通过ctx.flush()刷新到线。 或者,为了简洁,您可以调用ctx.writeAndFlush(msg)

  3. 如果再次运行 telnet localhost 8080 命令,将看到服务器发回您已发送给它的内容。

EchoServerHandler.java 文件的代码如下所示 -

package com.zaixian.netty.echo;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

/**
 * Handler implementation for the echo server.
 */
@Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf in = (ByteBuf) msg;
        System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8));
        ctx.write(in);
        //ctx.write(msg);
        ctx.flush();
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        cause.printStackTrace();
        ctx.close();
    }
}

EchoClientHandler.java 文件的代码如下所示 -

package com.zaixian.netty.echo;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

/**
 * Handler implementation for the echo client.  It initiates the ping-pong
 * traffic between the echo client and server by sending the first message to
 * the server.
 */
public class EchoClientHandler extends ChannelInboundHandlerAdapter {

    private final ByteBuf firstMessage;

    /**
     * Creates a client-side handler.
     */
    public EchoClientHandler() {
        firstMessage = Unpooled.buffer(EchoClient.SIZE);
        for (int i = 0; i < firstMessage.capacity(); i ++) {
            firstMessage.writeByte((byte) i);
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        System.out.println("Connected");
        ctx.writeAndFlush(Unpooled.copiedBuffer("This msg from clien!", CharsetUtil.UTF_8));
        //ctx.writeAndFlush(firstMessage);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf in = (ByteBuf) msg;
        System.out.println("Msg Form Server: " + in.toString(CharsetUtil.UTF_8));
        //ctx.write(msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
       ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        cause.printStackTrace();
        ctx.close();
    }
}

运行测试:

首页先运行 EchoServer.java, 然后再运行 EchoClient.java ,得到如下结果 -

EchoServer.java输出结果如下:

三月 01, 2017 3:10:56 上午 io.netty.handler.logging.LoggingHandler channelRegistered
信息: [id: 0xe42c7db3] REGISTERED
三月 01, 2017 3:10:56 上午 io.netty.handler.logging.LoggingHandler bind
信息: [id: 0xe42c7db3] BIND: 0.0.0.0/0.0.0.0:8007
三月 01, 2017 3:10:56 上午 io.netty.handler.logging.LoggingHandler channelActive
信息: [id: 0xe42c7db3, L:/0:0:0:0:0:0:0:0:8007] ACTIVE
三月 01, 2017 3:11:07 上午 io.netty.handler.logging.LoggingHandler channelRead
信息: [id: 0xe42c7db3, L:/0:0:0:0:0:0:0:0:8007] RECEIVED: [id: 0xf1e9f9a2, L:/127.0.0.1:8007 - R:/127.0.0.1:59492]
Server received: This msg from clien!

EchoClient.java输出结果如下:

Connected
Msg Form Server: This msg from clien!

消息“This msg from clien!”先是从 EchoClient.java 中发给服务器,服务器收到这消息后又发回给客户端。


上一篇: Netty实践入门-编写简单服务器 下一篇: Netty实践-时间服务器