Netty学习6之TCP实例

实践

创建项目

使用了Springboot来创建.毕竟好多开箱即用的东东.用着很舒服.
创建界面必选一个框架:Lombok.
不写getter和setter方法真的爽很多

导入jar包

Netty是在B站学习的.而那个老师的jar 是 下载下来手动导入的.emmm.
4.1.2版本的jar

编写服务端程序

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

        // 只处理连接请求
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        // 只处理也客户端的业务处理
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        // 他们俩个都是无限循环

        // 服务器端启动的对象:可以配置参数
        ServerBootstrap serverBootStarp = new ServerBootstrap();
        // 使用链式编程设置
        serverBootStarp.group(bossGroup,workerGroup)
                .channel(NioServerSocketChannel.class)
                // 线程队列的连接个数
                .option(ChannelOption.SO_BACKLOG,128)
                // 设置保持活动连接状态
                .childOption(ChannelOption.SO_KEEPALIVE,true)
                // 给 WorkerGroup 设置 对应的处理器
                // 在 socketChannel 设置到 WorkerGroup的 selector 上时,需要的处理器
                // 可以自定义,也可以是Netty提供
                .childHandler(new ChannelInitializer<SocketChannel>() {// 创建一个通道初始化对象
                    //  给pipeline 设置处理器
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline()
                    // 在管道的最后增加处理器
                    // 自己继承 ChannelInboundHadlerAdapter,重写了方法
                    .addLast(new NettyServerHandler());
                    }
                });
        // 绑定一个端口并同步,生成了一个ChannelFuture对象
        // 启动服务器,绑定端口
        ChannelFuture ch = serverBootStarp.bind(6668).sync();

        // 对关闭通道进行监听
        // 有了 关闭通道的消息或事件时,采取处理
        // 关于到异步 模型
        ch.channel().closeFuture().sync();

    }

分析

之前说过,服务端分为俩部分,一部分为BossGroup,另一部分是WorkerGroup. 
1. 都拥有自己的Handler:用于监测是否有数据到达
2. 有自己的线程池:规定了活动的线程数量等等一些信息
3. 有bootServerstarp:启动助手,设置一些信息:
4. 还有 sync() 方法,涉及到了 netty的异步模型
... ...

自定义Handler

Client
public class NettyClientHandler extends ChannelInboundHandlerAdapter {

    /**
     * 当通道就绪,就会触发该方法
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("client" + ctx);
        ChannelFuture channelFuture = ctx.writeAndFlush(Unpooled.copiedBuffer("hello server", Charset.forName("utf8")));
    }

    /**
     * 当通道有读取事件时,会触发
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    }


    /**
     * 发生了异常怎么办
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    }
}

Server
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    /**
     * 读取实际数据,可以在这里读取客户端发送的消息
     * @param ctx 上下文对象,含有 管道:pipeLine,通道,SocketChannel
 *              pipeline 可以包含很多 handler
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx,Object msg) throws Exception {
    }

    /**
     * 数据读取完毕
     *
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx){
    }

    /**
     * 处理异常的方法
     * TODO  发生了关闭管道的事件
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    }
}

编写客户端程序

public static void main(String[] args) throws InterruptedException {
        EventLoopGroup eventExecutors = null;
        try{
            // 客户端只需要一个事件循环组
            eventExecutors = new NioEventLoopGroup();
            // 客户端启动助手
            Bootstrap bootstrap = new Bootstrap();
            // 设置相关的参数
            // 设置相关的group,想关的线程组
            bootstrap.group(eventExecutors)
                    // 设置客户端通道的实现类型|实现类
                    .channel(NioSocketChannel.class)
                    // 服务器发送的消息,需要自己编写
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            // 加入自己的处理其
                            socketChannel.pipeline().addLast(new NettyClientHandler());
                        }
                    });
            System.out.println("客户端准备好了");
            // sync() 涉及到netty的异步模型
            ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6668).sync();
            // 给关闭通道进行监听
            // 非阻塞的
            channelFuture.channel().closeFuture().sync();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            // 优雅关闭
            eventExecutors.shutdownGracefully();
        }
    }
发布了36 篇原创文章 · 获赞 1 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/DXH9701/article/details/103624013