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實踐-時間伺服器