Netty实战学习笔记01——简单Echo服务器编写

news/2024/7/7 19:47:11 标签: netty

十一假期以过去一大半,本来是计划每天一篇学习记录进行更新的,结果今天才开始写第一篇博文。这就是为什么我还是一个菜鸟的原因。既然不能每天进步一点,那么就每周进步一点!

最近博主新入手一本《Netty实战》,从今天开始博主就来记录一下netty的学习笔记,便于以后回来翻看。

闲言少叙,书归正传。
编写echo服务器,即收到消息后即时回复的服务端代码。

1.maven依赖

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.30.Final</version>
        </dependency>

使用netty只需要引用一个jar包即可。

2.创建channelHandler,即业务逻辑部分

package com.youyou.netty.learn.echo;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.Date;

/**
 * //TODO 添加类/接口功能描述
 *
 * @author 刘朋
 * <br/>date 2019-10-05
 */
@ChannelHandler.Sharable //标示一个ChannelHandler可以被多个Channel安全地共享
public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    /**
     * 对于每一个传入的消息都要调用
     * @param ctx
     * @param msg
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf in = (ByteBuf) msg;

        //将消息记录到控制台
        System.out.println(new Date()+"服务器接收到消息:" + in.toString(CharsetUtil.UTF_8));
        //将接收到的消息写给发送者,而不冲刷出站消息
        ctx.write(in);

    }

    /**
     * 通知ChannelInboundHandler最后一次对channelRead()的调用是当前批量读取中的最后一条消息
     * 就是接到一波数据后,最后调用的方法
     * @param ctx
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        //将未决消息冲刷到远程节点,并关闭该Channel,如果不需要每次服务器接收到消息之后立即断开连接,需要注释掉这一行
//        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER);
    }

    /**
     * 如果执行异常则回调此方法
     * @param ctx
     * @param cause
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        //关闭该channle
        ctx.close();
    }
}

3.编写引导服务器,即服务启动类。
 

package com.youyou.netty.learn.echo;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.net.InetSocketAddress;

/**
 * //TODO 添加类/接口功能描述
 *
 * @author 刘朋
 * <br/>date 2019-10-05
 */
public class EchoServer {

    private final int port = 8080;

    public static void main(String[] args) throws InterruptedException {

        new EchoServer().start();
    }

    private void start() throws InterruptedException {
        final EchoServerHandler echoServerHandler = new EchoServerHandler();
        //创建EventLoopGroup
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            //创建ServerBootstrap
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(group)
                    .channel(NioServerSocketChannel.class)//指定NIO传输Channel
                    .localAddress(new InetSocketAddress(port))//使用指定的端口设置套接字地址
                    //添加一个EchoServerHandler到子Channel的ChannelPipeline
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) {
                            socketChannel.pipeline().addLast(echoServerHandler);
                        }
                    });
            //异步地绑定服务器;调用sync()方法阻塞等待直到绑定完成
            ChannelFuture f = serverBootstrap.bind().sync();
            //获取Channel的closeFuture并且阻塞当前线程直到它完成
            f.channel().closeFuture().sync();
        }finally {
            //关闭EventLoopGroup释放所有的资源
            group.shutdownGracefully().sync();
        }
    }

}

通过以上两个类,简单的echo服务器我们已经写好了 ,这样就可以使用tcp助手进行测试了,测试结果如下:

 

 

 


http://www.niftyadmin.cn/n/860590.html

相关文章

java实现递归菜单树

本文实例为大家分享了java实现递归菜单树的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 1.表结构 SET FOREIGN_KEY_CHECKS0;-- ---------------------------- -- Table structure for menu -- ---------------------------- DROP TABLE IF EXISTS menu; CREATE …

Netty实战学习笔记02——简单Echo客户端编写

今天来继续记录Echo的下半部分&#xff0c;Echo客户端的编写。 这里我们需要简单介绍一下我们所需要做的内容&#xff1a; 为初始出啊客户端&#xff0c;创建一个Bootstarp实例&#xff1b;为进行事件处理分配一个NIOEventLoopGroup实例&#xff0c;其中事件处理包括创建新的…

Git怎么配置别名

这篇文章主要介绍“Git怎么配置别名”&#xff0c;在日常操作中&#xff0c;相信很多人在Git怎么配置别名问题上存在疑惑&#xff0c;小编查阅了各式资料&#xff0c;整理出简单好用的操作方法&#xff0c;希望对大家解答”Git怎么配置别名”的疑惑有所帮助&#xff01;接下来&…

Java基础学习03——通过继承Comparable方法实现排序

今天来记录一下一个知识点&#xff0c;学了这个功能点之后就可轻松的将对象进行排序了。 只需要实现Comparable接口即可通过Collections.sort()方法进行排序了。 示例代码如下&#xff1a; package com.youyou.util;import lombok.Data;import java.util.ArrayList; import …

怎么使用Git远程删除某个历史提交记录

这篇文章主要介绍“怎么使用Git远程删除某个历史提交记录”的相关知识&#xff0c;小编通过实际案例向大家展示操作过程&#xff0c;操作方法简单快捷&#xff0c;实用性强&#xff0c;希望这篇“怎么使用Git远程删除某个历史提交记录”文章能帮助大家解决问题。 引言 在开发中…

文本框限制输入内容

只能输入正整数 <input type"text" name"speed" onkeyup"valuevalue.replace(/^(0)|[^\d]/g,)"placeholder"请输入车辆速度"> 限制最大长度 <input type"text" maxlength"5" />

前端笔记04——layui上传组件layui.upload的使用

layui上传组件layui.upload的使用入下&#xff1a;现在记录下来&#xff0c;省的以后都找不到了 upload.render({elem: #importBtn,url: api "/excelImport/",size:1024*3,data: {id: function() {return $(#p_id).val();}},accept: file,exts: xlsx|xls,done: fun…

SpringBoot学习笔记26——注解实现日志类log的注入

最近学到了一个新知识 &#xff0c;就是在日志记录时可以通过注解的形式进行log实例的注入&#xff0c;这样我们又可以少写一行样板代码。 原来我使用log类的时候记录日志时是这样的。 package com.youyou.util.test;import lombok.extern.slf4j.Slf4j; import org.slf4j.Log…