五、netty tcp服务端

所有文章

https://www.cnblogs.com/lay2017/p/12922074.html

 

正文

要构建netty的tcp服务端,你需要

1.创建EventLoopGroup

2.配置一个ServerBootStrap

3.创建ChannelInitializer

4.启动服务

代码如下

EventLoopGroup group = new NioEventLoopGroup();

try{
    ServerBootstrap serverBootstrap = new ServerBootstrap();
    serverBootstrap.group(group);
    serverBootstrap.channel(NioServerSocketChannel.class);
    serverBootstrap.localAddress(new InetSocketAddress("localhost", 9999));

    serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
        protected void initChannel(SocketChannel socketChannel) throws Exception {
            socketChannel.pipeline().addLast(new HelloServerHandler());
        }
    });
    ChannelFuture channelFuture = serverBootstrap.bind().sync();
    channelFuture.channel().closeFuture().sync();
} catch(Exception e){
    e.printStackTrace();
} finally {
    group.shutdownGracefully().sync();
}

创建EventLoopGroup

第一步是创建EventLoopGroup,相对比较简单,如

EventLoopGroup group = new NioEventLoopGroup();

创建ServerBootstrap

第二步是创建ServerBootstrap

ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(group);
serverBootstrap.channel(NioServerSocketChannel.class);
serverBootstrap.localAddress(new InetSocketAddress("localhost", 9999));

group方法把EventLoopGroup绑定到了ServerBootstrap上

EventLoopGroup是NioEventLoopGroup实现,所以这里要指明channel是NioServerSocketChannel

最后通过InetSocketAddress指明domain + port

创建ChannelInitializer

第三步是创建ChannelInitializer

serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        socketChannel.pipeline().addLast(new HelloServerHandler());
    }
});

ChannelInitializer绑定到了serverBootstrap上

pipeline添加ChannelHandler

启动

最后一步,启动服务

ChannelFuture channelFuture = serverBootstrap.bind().sync();

bind方法返回ChannelFuture,可以知道绑定到domain  + port什么时候完成。sync方法会等待服务启动完成

HelloChannelHandler

最后给出HelloChannelHandler代码

public class HelloServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf inBuffer = (ByteBuf) msg;

        String received = inBuffer.toString(CharsetUtil.UTF_8);
        System.out.println("Server received: " + received);

        ctx.write(Unpooled.copiedBuffer("Hello " + received, CharsetUtil.UTF_8));
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
                .addListener(ChannelFutureListener.CLOSE);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

channelRead方法是从SocketChannel中read数据的时候触发,channelReadComplete方法是没有可读数据的时候触发,exceptionCaught方法是从socket中read数据或者write数据的时候异常触发

 

posted @ 2020-05-20 11:43  __lay  阅读(1084)  评论(0编辑  收藏  举报