基于 Netty 框架的 Java TCP 服务器端实现,用于启动一个 TCP 服务器来处理客户端的连接和数据传输

代码:

javascript 复制代码
package com.example.tpson_tcp;
 
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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 io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.stereotype.Service;
 
import javax.annotation.PostConstruct;
 
/**
 * Netty服务端类,用于启动TCP服务器。
 */
@Service
public class NettyServer {
 
    /**
     * 在对象初始化后自动调用的方法,用于启动服务器。
     * 无参数和返回值。
     */
    @PostConstruct
    public void main() {
        // 创建EventLoopGroup用于处理网络事件
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            // 配置服务器启动参数
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class) // 指定使用的NIO通道类
                    .childHandler(new ChannelInitializer<SocketChannel>() { // 设置通道初始化处理器
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            // 在通道中添加处理链,用于解码、编码和处理设备数据
                            ch.pipeline().addLast(new StringDecoder());
                            ch.pipeline().addLast(new StringEncoder());
                            ch.pipeline().addLast(new DeviceDataHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128) // 设置连接队列大小
                    .childOption(ChannelOption.SO_KEEPALIVE, true); // 启用TCP KeepAlive
 
            // 绑定端口并启动服务器
            ChannelFuture channelFuture = serverBootstrap.bind(8092).sync();
            // 等待服务器关闭
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            // 异常处理,抛出运行时异常
            throw new RuntimeException(e);
        } finally {
            // 关闭EventLoopGroup,释放资源
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}

代码解释:

1. 包导入部分

java

复制代码
package com.example.tpson_tcp;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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 io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
  • package com.example.tpson_tcp;:指定该类所属的包名。
  • 后续一系列 import 语句引入了 Netty 框架的相关类,用于网络编程。ServerBootstrap 用于配置和启动服务器;EventLoopGroup 是用于处理网络事件的线程池;StringDecoderStringEncoder 用于对字符串进行编解码。
  • org.springframework.stereotype.Service 表明这是一个 Spring 服务类。
  • javax.annotation.PostConstruct 用于标记一个方法,该方法会在对象初始化后自动调用。

2. 类定义和注解

java

  • @Service:这是 Spring 框架的注解,将 NettyServer 类标记为一个服务组件,Spring 会自动扫描并管理这个类的实例。
  • public class NettyServer:定义了一个名为 NettyServer 的公共类。

3. main 方法

java

复制代码
@PostConstruct
public void main() {
  • @PostConstruct:该注解表明 main 方法会在 NettyServer 类的实例被创建并初始化后自动调用。
  • public void main():定义了一个公共的无返回值方法 main

4. 创建 EventLoopGroup

java

复制代码
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
  • NioEventLoopGroup 是 Netty 提供的基于 Java NIO 的事件循环组,用于处理网络事件。
  • bossGroup 主要负责接受客户端的连接请求。
  • workerGroup 负责处理已经建立的连接的读写操作。

5. 配置服务器启动参数

java

复制代码
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
        .channel(NioServerSocketChannel.class) 
        .childHandler(new ChannelInitializer<SocketChannel>() { 
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast(new StringDecoder());
                ch.pipeline().addLast(new StringEncoder());
                ch.pipeline().addLast(new DeviceDataHandler());
            }
        })
        .option(ChannelOption.SO_BACKLOG, 128) 
        .childOption(ChannelOption.SO_KEEPALIVE, true); 
  • ServerBootstrap 用于配置和启动服务器。
  • group(bossGroup, workerGroup):指定使用的 EventLoopGroup
  • channel(NioServerSocketChannel.class):指定使用的 NIO 通道类,用于接受客户端的连接。
  • childHandler:设置通道初始化处理器,当有新的连接建立时,会调用 initChannel 方法。在该方法中,向通道的处理链中添加了 StringDecoderStringEncoderDeviceDataHandlerStringDecoder 用于将接收到的字节数据解码为字符串,StringEncoder 用于将字符串编码为字节数据发送出去,DeviceDataHandler 用于处理具体的业务逻辑。
  • option(ChannelOption.SO_BACKLOG, 128):设置连接队列的大小,即允许等待处理的最大连接数。
  • childOption(ChannelOption.SO_KEEPALIVE, true):启用 TCP 的 KeepAlive 机制,用于检测长时间空闲的连接是否仍然有效。

6. 绑定端口并启动服务器

java

复制代码
ChannelFuture channelFuture = serverBootstrap.bind(8092).sync();
channelFuture.channel().closeFuture().sync();
  • serverBootstrap.bind(8092):将服务器绑定到指定的端口 8092。
  • sync() 方法是一个同步方法,会阻塞当前线程,直到绑定操作完成。
  • channelFuture.channel().closeFuture().sync():等待服务器关闭,会阻塞当前线程,直到服务器的通道关闭。

7. 异常处理和资源释放

java

复制代码
} catch (InterruptedException e) {
    throw new RuntimeException(e);
} finally {
    workerGroup.shutdownGracefully();
    bossGroup.shutdownGracefully();
}
  • catch (InterruptedException e):捕获 InterruptedException 异常,当线程在等待过程中被中断时会抛出该异常,将其包装成 RuntimeException 重新抛出。
  • finally 块:无论是否发生异常,都会执行该块中的代码,调用 shutdownGracefully() 方法来优雅地关闭 workerGroupbossGroup,释放资源。
相关推荐
CppPlayer-程序员阿杜2 天前
字节二面:TCP 链接中,接收方不调用 recv,会出现什么情况?——拆解大厂面试题(校招)
网络协议·计算机网络·tcp·c++面试·c++面试真题
kfepiza3 天前
`accept_ra` 和 `autoconf` 和 `forwarding` 的关系 笔记250404
linux·网络·笔记·tcp/ip·智能路由器·ip·tcp
W说编程5 天前
《UNIX网络编程卷1:套接字联网API》第5章 TCP客户服务器程序示例
c语言·网络·网络协议·tcp/ip·unix·tcp
kfepiza6 天前
Debian/Ubuntu的networking的`/etc/network/interfaces`配置文件,如何配置route路由
linux·网络·tcp/ip·ubuntu·debian·ip·tcp
UestcXiye10 天前
《TCP/IP网络编程》学习笔记 | Chapter 22:重叠 I/O 模型
c++·计算机网络·网络编程·ip·tcp
沧海一笑-dj11 天前
【鸿蒙开发】Hi3861学习笔记- TCP客户端
网络·socket·harmonyos·tcp·tcp客户端·套接字·hi3861
UestcXiye13 天前
《TCP/IP网络编程》学习笔记 | Chapter 21:异步通知 I/O 模型
c++·计算机网络·ip·tcp
阿尔泰科技官方14 天前
智能监测体系--护航 LNG 储罐安全!
测试·以太网·tcp·仪器仪表·数据采集卡·lng 储罐