目标

上一章节我们初步了解了Netty实现一个服务端程序,并本章节我们要了解如何读取客户端发送过来的数据,并且向客户端发送数据

实现一个echo服务

echo服务就是收到什么数据就直接打印出来

同样的我们需要创建一个handler来处理客户端发送的数据,然后把这个handler添加到pipeline中。


package io.netty.example.echo;

import io.netty.buffer.ByteBuf;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelHandlerAdapter;

public class EchoServerHandler extends ChannelInboundHandlerAdapter{

    @Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) {
	    ByteBuf in = (ByteBuf) msg;
	    try {
	        while (in.isReadable()) {
	            System.out.print((char) in.readByte());
	            System.out.flush();
	        }
	    } finally {
	        ReferenceCountUtil.release(msg);
	    }
	}
}

收到的数据是ByteBuf格式,读取缓冲区中所有可读的字节,并转换为char类型打印出来。最后重要的是要记得要显示的释放资源。
如果每次要手动写释放资源的代码很麻烦(况且还容易粗心漏掉)那么可以修改代码将继承的ChannelHandlerAdapter修改为 SimpleChannelInboundHandler。我们只需要重写channelRead0 抽象,channelRead方法内部会调用channelRead0并在执行完成后帮助我们释放掉缓冲区

实现一个时间服务器

当客户端连接上服务端时,服务端立即向客户端返回服务器当时时间信息

package io.netty.example.time;

public class TimeServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(final ChannelHandlerContext ctx) {
        final ByteBuf time = ctx.alloc().buffer(4);
        time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));
        
        final ChannelFuture f = ctx.writeAndFlush(time);
        f.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) {
                assert f == future;
                ctx.close();
            }
        });
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}
  1. 当客户端连接到服务器后,会触发handler中的 channelActive方法,通过参数ChannelHandlerContext 我们即可操作通道写数据。
  2. 向通道中写数据也是需要通过缓冲区的,那么我们就要创建一个缓冲区存放我们要写给客户端的数据,ctx.alloc().buffer(4) 动态申请4字节内存。通过ctx.writeAndFlush把缓冲区数据写入通道,并flush出去。如果只调用write方法,客户端并不会马上收到数据。
  3. 写完数据后我们需要关闭连接,那么我们就需要知道数据是否已经写入完成,因此上面代码中需要添加listener,并在完成后通过ctx.close关闭通道。

到此我们已经初步了解到了如何用Netty实现服务端并读写数据,下章我们要学习如何编写客户端的程序

posted on 2024-06-01 14:13  猿来就是尔  阅读(1)  评论(0)    收藏  举报  来源