Netty的EchoServer與Client

服務(wù)端

EchoServerHandler - 消息處理

@ChannelHandler.Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws FileNotFoundException {
        //ReferenceCountUtil.release(msg);
        ByteBuf buf = (ByteBuf)msg;
        System.out.println("Server recevied:"+ buf.toString(Charset.forName("UTF-8")));
        ctx.write(buf);
    }



    final ByteBuf byteBuffer = Unpooled.unreleasableBuffer(
            Unpooled.copiedBuffer("hello world!\r\n", CharsetUtil.UTF_8));

    @Override
    public void channelActive(ChannelHandlerContext ctx){
        ChannelFuture cf= ctx.writeAndFlush(byteBuffer.duplicate());
        cf.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()){
                    System.out.println("Write successful!");
                }else{
                    System.out.println("Write Error!");
                    future.cause().printStackTrace();
                }
            }
        });
    }


    @Override
    public void channelReadComplete(ChannelHandlerContext ctx){
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
                .addListener(ChannelFutureListener.CLOSE); //將未決消息沖刷到遠(yuǎn)程節(jié)點且關(guān)閉該Channel
    }


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



}

EchoServer- 啟動程序


public class EchoServer {

    public static void main(String[] args) throws InterruptedException {
        EchoServer echoNettyServer =  new EchoServer();
        echoNettyServer.start(9981);
    }

    public void start(int port) throws InterruptedException {
        final EchoServerHandler serverHandler = new EchoServerHandler();
        final ByteBuf byteBuffer = Unpooled.unreleasableBuffer(
                Unpooled.copiedBuffer("HI!\r\n", Charset.forName("UTF-8")));

        EventLoopGroup group = new NioEventLoopGroup(); //非阻塞方式
        try{
            ServerBootstrap b = new ServerBootstrap(); //創(chuàng)建ServerBootstrap
            b.group(group)//NioSctpChannel
                    .channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(serverHandler);
                        }//每個已接收的連接都調(diào)用它

                    });

                ChannelFuture f = b.bind().sync();  //異步綁定服務(wù)器涡驮,調(diào)用sync()方法阻塞等待直接綁定完成
                f.channel().closeFuture().sync(); //獲取Channel的CloseFuture,并且阻塞當(dāng)前線程直接它完成
        }finally {
            group.shutdownGracefully().sync();
        }
    }


}

客戶端

EchoClientHandler --消息處理

/**
 * SimpleChannelInboundHandler:
 *  1. 當(dāng)channnelRead0方法完成時稳吮,已傳入的消息并且已處理完它了。當(dāng)方法返回時织咧,SimpleChannelInboundHandler負(fù)責(zé)釋放指向保存該消息的ByteBuffer的內(nèi)存引用
 *  2. 而服務(wù)端Handler,需要將傳入的消息回傳給發(fā)送者庄新,而write()是異步操作扶踊,直接ChannelRead()方法返回后可能仍然沒有完成。
 */
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
    /**
     * 接收到消息朱巨,服務(wù)器發(fā)送的消息可能會被分塊接收(并非一次性全部接收)
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
        System.out.println("Client received:"+msg.toString(CharsetUtil.UTF_8));
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx){
        ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!!", CharsetUtil.UTF_8));
    }

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


}

EchoClient - 啟動程序

public class EchoClient {

    public static void main(String[] args) throws InterruptedException {
        String host = "localhost";
        int port = 9981;
        new EchoClient().start(host,port);
    }

    public void start(String host,int port) throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();

        Bootstrap b = new Bootstrap();
        try {
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .remoteAddress(new InetSocketAddress(host,port))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new EchoClientHandler())

                            ;
                        }
                    });

            ChannelFuture f = b.connect().sync(); //連接到遠(yuǎn)程節(jié)點,阻塞等待直接連接完成

            f.channel().closeFuture().sync();//阻塞枉长,直接Channel關(guān)閉
            f.addListener(
                    new ChannelFutureListener() {
                        @Override
                        public void operationComplete(ChannelFuture future) throws Exception {
                            if (future.isSuccess()){
                                System.out.println("Connection established!");
                            }else{
                                System.out.println("Connection attempt failed!");
                                future.cause().printStackTrace();;
                            }
                        }
                    }
            );
        }finally {
            group.shutdownGracefully().sync();
        }

    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冀续,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子必峰,更是在濱河造成了極大的恐慌洪唐,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吼蚁,死亡現(xiàn)場離奇詭異凭需,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門功炮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來溅潜,“玉大人,你說我怎么就攤上這事薪伏」隼剑” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵嫁怀,是天一觀的道長设捐。 經(jīng)常有香客問我,道長塘淑,這世上最難降的妖魔是什么萝招? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮存捺,結(jié)果婚禮上槐沼,老公的妹妹穿的比我還像新娘。我一直安慰自己捌治,他們只是感情好岗钩,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肖油,像睡著了一般兼吓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上森枪,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天视搏,我揣著相機與錄音,去河邊找鬼县袱。 笑死浑娜,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的显拳。 我是一名探鬼主播棚愤,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼搓萧,長吁一口氣:“原來是場噩夢啊……” “哼杂数!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瘸洛,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤揍移,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后反肋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體那伐,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了罕邀。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片畅形。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖诉探,靈堂內(nèi)的尸體忽然破棺而出日熬,到底是詐尸還是另有隱情,我是刑警寧澤肾胯,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布竖席,位于F島的核電站,受9級特大地震影響敬肚,放射性物質(zhì)發(fā)生泄漏毕荐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一艳馒、第九天 我趴在偏房一處隱蔽的房頂上張望憎亚。 院中可真熱鬧,春花似錦弄慰、人聲如沸虽填。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斋日。三九已至,卻和暖如春墓陈,著一層夾襖步出監(jiān)牢的瞬間恶守,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工贡必, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留兔港,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓仔拟,卻偏偏與公主長得像衫樊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子利花,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345