【韩顺平】尚硅谷Netty视频教程

《尚硅谷 - Netty 核心技术及源码剖析教程:从 IO 模型到高性能通信,吃透底层原理》不仅深入介绍了Netty的核心原理,还通过大量的示例代码帮助读者理解底层实现和实际应用。在这里,我们将通过一个简单的代码示例,演示Netty框架如何构建一个高效的网络通信应用。

1. Netty的基础代码示例

在本例中,我们将创建一个简单的Echo服务器和客户端。服务器接收到客户端的消息后,会原样返回。

1.1 EchoServer(服务器端代码)

java 复制代码
package com.example.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
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;

public class EchoServer {
    private final int port;

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

    public void start() throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup(); // 负责接收客户端连接
        EventLoopGroup workerGroup = new NioEventLoopGroup(); // 负责处理I/O操作

        try {
            ServerBootstrap b = new ServerBootstrap(); // 启动引导类
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class) // 使用NIO传输类型
             .childHandler(new ChannelInitializer<SocketChannel>() { // 初始化每个接入的客户端Channel
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast(new EchoServerHandler()); // 添加处理逻辑
                 }
             });

            ChannelFuture f = b.bind(port).sync(); // 绑定端口,开始接收进来的连接
            f.channel().closeFuture().sync(); // 等待服务器关闭
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new EchoServer(8080).start(); // 启动服务器,监听8080端口
    }
}

1.2 EchoServerHandler(服务器端的Handler)

java 复制代码
package com.example.netty;

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

public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 将接收到的消息写回客户端
        ByteBuf in = (ByteBuf) msg;
        System.out.println("Server received: " + in.toString(io.netty.util.CharsetUtil.UTF_8));
        ctx.write(msg); // 发送到客户端
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush(); // 刷新所有写操作
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close(); // 关闭连接
    }
}

1.3 EchoClient(客户端代码)

java 复制代码
package com.example.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
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.NioSocketChannel;

public class EchoClient {
    private final String host;
    private final int port;

    public EchoClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void start() throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup(); // 事件循环组

        try {
            Bootstrap b = new Bootstrap(); // 启动引导类
            b.group(group)
             .channel(NioSocketChannel.class) // 使用NIO传输类型
             .handler(new ChannelInitializer<SocketChannel>() { // 初始化客户端Channel
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast(new EchoClientHandler()); // 添加处理逻辑
                 }
             });

            ChannelFuture f = b.connect(host, port).sync(); // 连接到服务器
            f.channel().closeFuture().sync(); // 等待关闭
        } finally {
            group.shutdownGracefully(); // 关闭线程池
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new EchoClient("localhost", 8080).start(); // 连接到localhost:8080
    }
}

1.4 EchoClientHandler(客户端的Handler)

java 复制代码
package com.example.netty;

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

public class EchoClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        String message = "Hello, Netty!";
        ByteBuf encoded = ctx.alloc().buffer(4 * message.length());
        encoded.writeBytes(message.getBytes());
        ctx.writeAndFlush(encoded); // 向服务器发送消息
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf in = (ByteBuf) msg;
        System.out.println("Client received: " + in.toString(io.netty.util.CharsetUtil.UTF_8));
        ctx.close(); // 关闭连接
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close(); // 关闭连接
    }
}

2. 代码解析

  1. 服务器端(EchoServer)

    • 使用ServerBootstrap来启动服务器,NioServerSocketChannel是Netty提供的一个实现TCP/IP协议的Channel类型。
    • ChannelInitializer初始化每个连接的Channel,并在其Pipeline中添加一个EchoServerHandler来处理收到的数据。
  2. 客户端(EchoClient)

    • 使用Bootstrap启动客户端,NioSocketChannel是客户端连接时的Channel类型。
    • 连接到服务器后,客户端发送一个简单的消息Hello, Netty!,并在接收到服务器响应后打印。
  3. 数据处理(Handler)

    • EchoServerHandler:负责接收客户端的消息并将其原样返回。
    • EchoClientHandler:客户端接收到服务器的回应后,打印返回的消息并关闭连接。

3. 运行效果

  1. 启动EchoServer服务器,监听8080端口。
  2. 启动EchoClient客户端,连接到服务器并发送Hello, Netty!
  3. 服务器接收到客户端消息后,原样返回给客户端,客户端打印出Server received: Hello, Netty!

4. 总结

通过这个简单的Echo服务器和客户端示例,展示了Netty框架的基础使用方法。Netty的核心优势在于其高性能的I/O处理、灵活的线程模型和强大的扩展能力。通过深入分析Netty的源码,开发者可以更好地理解底层的I/O模型和优化技术,从而在实际应用中充分发挥Netty的高效能。

相关推荐
神奇小汤圆17 分钟前
Unsafe魔法类深度解析:Java底层操作的终极指南
后端
神奇小汤圆1 小时前
浅析二叉树、B树、B+树和MySQL索引底层原理
后端
文艺理科生1 小时前
Nginx 路径映射深度解析:从本地开发到生产交付的底层哲学
前端·后端·架构
千寻girling1 小时前
主管:”人家 Node 框架都用 Nest.js 了 , 你怎么还在用 Express ?“
前端·后端·面试
南极企鹅1 小时前
springBoot项目有几个端口
java·spring boot·后端
Luke君607971 小时前
Spring Flux方法总结
后端
define95271 小时前
高版本 MySQL 驱动的 DNS 陷阱
后端
忧郁的Mr.Li2 小时前
SpringBoot中实现多数据源配置
java·spring boot·后端
暮色妖娆丶2 小时前
SpringBoot 启动流程源码分析 ~ 它其实不复杂
spring boot·后端·spring
Coder_Boy_3 小时前
Deeplearning4j+ Spring Boot 电商用户复购预测案例中相关概念
java·人工智能·spring boot·后端·spring