Netty简单应用

1.服务端构建

  • 接收客户端请求,打印请求消息;
  • 消息采用内置String作为编码与解码器;
  • 开启信息输入监听线程,发送消息至客户端;

1.1 服务端消息处理类

java 复制代码
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.ArrayList;
import java.util.List;

/**
 * @author : luobei
 * @date : 2024/10/23 11:16
 * @Description : 处理类:处理channel接收到的消息
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    public static List<Channel> channelList = new ArrayList<Channel>();

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        channelList.add(ctx.channel());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("服务端收到消息:"+msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("服务端读取数据异常:");
        cause.printStackTrace();
        ctx.close();
    }
}

1.2 服务端启动类

java 复制代码
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
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 io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author : luobei
 * @date : 2024/10/23 11:03
 */
public class NettyServerProvider {

    private int port;
    public NettyServerProvider(int port){
        this.port = port;
    }

    //netty服务端启动
    public void start() throws InterruptedException {
        //用来接收进来的连接
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //用来处理已经被接收的连接,bossGroup接收到连接就会把连接信息注册到workerGroup上
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            //nio服务的启动类
            ServerBootstrap bootstrap = new ServerBootstrap();
            //配置nio服务参数
            bootstrap.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class) //说明一个新的Channel
                    .option(ChannelOption.SO_BACKLOG,128) //设置Tcp最大缓存连接个数
                    .childOption(ChannelOption.SO_KEEPALIVE,true) //设置保持连接
                    .handler(new LoggingHandler(LogLevel.INFO)) //设置打印日志级别
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socket) throws Exception {
                            //管道注册handler
                            ChannelPipeline pipeline = socket.pipeline();
                            //编码通道处理
                            pipeline.addLast("decode",new StringDecoder());
                            //转码通道处理
                            pipeline.addLast("encode",new StringEncoder());
                            //处理接收到的请求
                            pipeline.addLast(new NettyServerHandler());
                        }
                    });
            System.out.println("--------------服务端启动--------------");

            //监听输入框消息并发送给所有客户端
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        while (true){
                            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
                            String msg = null;

                                msg = in.readLine();
                            if (NettyServerHandler.channelList.size()>0){
                                for (Channel channel : NettyServerHandler.channelList) {
                                    channel.writeAndFlush(msg);
                                }
                            }
                        }
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();

            //绑定端口,开始接收连接
            ChannelFuture channelFuture = null;

            channelFuture = bootstrap.bind(port).sync();
            channelFuture.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new NettyServerProvider(8888).start();
    }

}

2.客户端构建

  • 发起请求,与服务端建立连接;
  • 监听服务端下发消息,并将信息打印出来;
  • 开启信息输入监听线程,将消息发送值服务端;

2.1 客户端消息处理类

java 复制代码
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * @author : luobei
 * @date : 2024/10/23 13:15
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter {

    public static Channel serverChannel = null;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        serverChannel = ctx.channel();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("客户端收到消息:"+msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("客户端读取数据异常:");
        cause.printStackTrace();
        ctx.close();
    }
}

2.2 客户端启动类

java 复制代码
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author : luobei
 * @date : 2024/10/23 13:20
 */
public class NettyClientServer {

    //要请求的IP地址
    private String ip;
    //服务器端口
    private int port;

    public NettyClientServer(String ip, int port){
        this.ip = ip;
        this.port = port;
    }

    //启动服务
    private void start() throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(bossGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE,true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline pipeline = socketChannel.pipeline();
                        pipeline.addLast("decode",new StringDecoder());
                        pipeline.addLast("encode",new StringEncoder());
                        socketChannel.pipeline().addLast(new NettyClientHandler());
                    }
                });
        System.out.println("-----------客户端启动-----------");
        ChannelFuture future = bootstrap.connect(ip,port).sync();
        String msg = "客户端发起连接请求";
        Channel channel = future.channel();
        channel.writeAndFlush(msg);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (true){
                        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
                        String msg = reader.readLine();
                        channel.writeAndFlush(msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public static void main(String[] args) throws InterruptedException {
        new NettyClientServer("127.0.0.1",8888).start();
    }
}
相关推荐
阳光宅男@李光熠4 小时前
【电子通识】一起学习TDK的EMC基础——电池兼容设计方法概述
java·前端·数据库
张宜强4 小时前
025 安居租赁 · 房屋租赁平台
java·课程设计
Java_2017_csdn5 小时前
ReentrantLock 与 Redis RLock 对比解读
java
YDS8295 小时前
Small Spring IOC篇:实现 Bean 的定义、注册、获取
java·spring
边境悍匪5 小时前
蜗牛学苑 Java 智能体学习 Day45|Knife4j+SpringBoot3、书城项目整合 MyBatis 思维导图复盘
java·开发语言·vue.js·学习·spring
我的xiaodoujiao5 小时前
Django 基础知识详细图文教程 9-Django 模板引擎 2
开发语言·数据库·后端·django
菜鸟~noob2335 小时前
【太空电子战】从CCS到Meadowlands:反通信系统的二十年演进史【含matlab代码】
开发语言·matlab
需要8265 小时前
Arthas 一个命令排查线上问题
java·jvm·spring·spring cloud
Kyrie_kk5 小时前
Java--ProcessBuilder操作系统进程
java·后端
SamDeepThinking6 小时前
关于java final关键字的可见性
java·后端·面试