【韩顺平】尚硅谷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的高效能。

相关推荐
用户9047066835720 小时前
Java Maven 是什么
后端
JoannaJuanCV20 小时前
error: can‘t find Rust compiler
开发语言·后端·rust
天天摸鱼的java工程师21 小时前
SpringBoot + Elasticsearch + Redis:八年 Java 开发手把手教你做 “不崩、不卡、不冲突” 的大学排课系统
后端
阿杆21 小时前
国产神级开源 OCR 模型,登顶全球第一!再次起飞!
后端·github·图像识别
CryptoRzz21 小时前
Java 对接印度股票数据源实现 http+ws实时数据
后端
调试人生的显微镜21 小时前
iOS 混淆工具链实战,多工具组合完成 IPA 混淆与加固(iOS混淆|IPA加固|无源码混淆|App 防反编译)
后端
渣哥1 天前
用错注入方式?你的代码可能早就埋下隐患
javascript·后端·面试
王中阳Go1 天前
我发现不管是Java还是Golang,懂AI之后,是真吃香!
后端·go·ai编程
亲爱的马哥1 天前
再见,TDuckX3.0 结束了
前端·后端·github