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

相关推荐
卷无止境3 小时前
独立开发者的"富矿地带":哪些垂直领域值得你押注一辈子?
后端·python
狼爷3 小时前
从零用 Java 构建 AI Agent 框架:JavaManus 设计与实现深度解析
后端·langchain·aigc
郑州光合科技余经理3 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
专业程序开发源4 小时前
springboot简历管理系统81389-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计
专业程序开发源4 小时前
springboot社区养老系统44071-计算机课程设计、毕业设计
vue.js·spring boot·后端·python·django·php·课程设计
小呆呆6664 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
周杰伦fans4 小时前
8GB显存下模型量化实战指南
人工智能·后端·c#
小蒜学长5 小时前
基于SpringBoot的佳新超市管理系统设计与实现系统(代码+数据库+LW)
java·数据库·spring boot·后端·佳新超市管理系统
IT_陈寒6 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
打工仔折腾 AI6 小时前
把AI Agent托管在家用电脑:UU远程终端与端口映射实测记录
人工智能·后端·python·langchain·ai agent 实战