Netty简单入门

软件要求

  • 最新版本Netty
  • JDK1.6以上

写一个Discard Server

在这个世界上最简单的协议不是 Hello world,而是DISCARD。该协议将一切接收到的数据全部舍弃,不做任何响应。因此,实现DISCARD协议,你唯一需要做的事情是忽略所有接收到的数据

  • 接下来,我们直接从handler的实现开始编写Discard服务,handler主要用于处理Netty产生的IO事件。
package discard.server;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * @ClassName DiscardHandler
 * @Description TODO
 * @Author xiuc_shi
 * @Date 2020/8/29 下午 1:17
 * @Version 1.0
 **/
public class DiscardHandler extends ChannelInboundHandlerAdapter {//(1)

    @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {//(2)
        //舍弃接收到的消息
        //        ((ByteBuf)msg).release();//(3)

        ByteBuf in = (ByteBuf)msg;
        while (in.isReadable()) {
            System.out.println((char)in.readByte());
            System.out.flush();
        }
    }

    @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {//(4)
        super.exceptionCaught(ctx, cause);
    }
}

为了看到服务器是否真的接收到数据,我们直接将数据打印出来。

  1. DiscardServerHandler继承了ChannelInboundHandlerAdapter,该类是ChannelInboundHandler的一个实现。ChannelInboundHandler提供了很多事件处理方法供你重写。
  2. 我们此处重写了channelRead()事件处理方法。当有新消息从客户端发出,该方法被调用来接收来自客户端的消息。在这个例子中,接收消息的类型是ByteBuf
  3. 对于DISCARD协议的实现,处理器会忽略接收到的消息。ByteBuf是一个引用计数对象(Reference-counted Object),因此必须通过调用release()方法显式释放。通常,channelRead()事件处理方法如下实现:
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
    try {
        // Do something with msg
    } finally {
        ReferenceCountUtil.release(msg);
    }
}
  1. 当处理器在处理事件是发生异常或者出现IO错误时,exceptionCaught()事件处理方法会触发抛出Throwable。大多数情况下,应当记录日志并且关闭相关的channel。实现不尽相同,根据你的需求,例如有时还希望在关闭连接之前发送错误码响应消息。
  • 至此,我们已经实现了DISCARD服务器的第一步。接下来,写main方法用来启动DiscardServerHandler服务。
package discard.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @ClassName Server
 * @Description TODO
 * @Author xiuc_shi
 * @Date 2020/8/29 下午 1:39
 * @Version 1.0
 **/
public class DiscardServer {
    private int port;

    public DiscardServer(int port) {
        this.port = port;
    }

    public void run() throws Exception{
        EventLoopGroup bossGroup = new NioEventLoopGroup();//(1)
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();//(2)
            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)//(3)
                .childHandler(new ChannelInitializer<SocketChannel>() {//(4)
                    @Override protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast(new DiscardHandler());
                    }
                }).option(ChannelOption.SO_BACKLOG, 128)//(5)
                .childOption(ChannelOption.SO_KEEPALIVE, true);//(6)
            //绑定端口,接收进来的连接
            ChannelFuture f = b.bind(port).sync();//(7)
            //等待服务器的socket关闭
            //在本例中,这不会发生,但你可以优雅地关闭你的服务
            f.channel().closeFuture().sync();

        }finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        int port = 8080;
        if(args.length > 0){
            port = Integer.parseInt(args[0]);
        }
        new DiscardServer(port).run();
    }
}
  1. NioEventLoopGroup是一个用于处理IO操作的多线程事件循环。Netty为不同的传输类型实现了多样的EventLoopGroup。我们在本例中实现的服务器端应用,使用了两个NioEventLoopGroup。其一,通常称为boss,接受一个进来的连接;其二,通常称为worker,处理boss循环器已经接受并注册到worker中的连接。多少个线程,以及线程和Channel之间的映射取决于EventLoopGroup的实现,或者通过构造器配置。
  2. ServerBootstrap是一个用于配置服务器的帮助类。你可以使用channel直接配置服务器。然而,这是一个乏味的过程,在大多数情况下你不需要做。
  3. 在此处,我们指明使用NioServerSocketChannel类来实例化一个新的Channel来接受进来的连接。
  4. 此处指明的处理器总是由新接受的channel来评估。(The handler specified here will always be evaluated by a newly accepted Channel.)ChannelInitializer是一个特殊的处理器,它被用于帮助用户初始化一个新的channel。类似于你想通过添加一些处理器到channel的ChannelPipeline以完成初始化。
  5. 你还能够设置参数来定制化你的Channel实现。本例实现的是TCP/IP服务器,因此可以设置socket options例如tcpNoDelaykeepAlive
  6. option()是服务于NioServerSocketChannel,接受进来的连接。而childOption()则是服务于父ServerChannel接受的Channels。
  7. 最后,绑定端口然后开启服务。

测试结果
我们使用cmd,输入命令talnet localhost 8080发起请求,输入1,2,3,4,控制台依次打印出来。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容