第一个Netty程序

By ref-nobody 创建时间 2025年4月21日 | 本文最后更新于 2025年4月21日 #bootstrap, #netty

最近在看dubbo的源代码,看到了org.apache.dubbo.rpc.protocol.tri.TripleProtocol#refer方法通过exchange->transporter->client的链路获取到了表示客户端连接的Client对象,里面使用到了netty4。因此参考dubbo创建Client的流程写一个netty的示例程序。

服务端搭建

简单使用命令在本地启动一个监听端口的服务端程序:nc -l 30888 我这里监听的30888端口。

客户端搭建

示例代码:

package io.itaiit.netty;

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 io.netty.util.concurrent.DefaultThreadFactory;

import java.net.InetSocketAddress;
import java.util.concurrent.ThreadFactory;

/**
 * macos系统中简单开启一个监听30888端口的服务:nc -l 30888,运行程序后,接收到客户端发送的消息
 */
public class NettyApp {

    // 参考dubbo的代码
    public static int DEFAULT_IO_THREADS = Math.min(Runtime.getRuntime().availableProcessors() + 1, 32);
    private static EventLoopGroup eventLoopGroup(int threads, String threadFactoryName) {
        ThreadFactory threadFactory = new DefaultThreadFactory(threadFactoryName, true);
        return new NioEventLoopGroup(threads, threadFactory);
    }

    private static InetSocketAddress getConnectAddress() {
        return new InetSocketAddress("localhost", 30888);
    }

    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup loopGroup = eventLoopGroup(DEFAULT_IO_THREADS, "M-NettyClientWorker");
        try {
            Bootstrap bootstrap = new Bootstrap();
            // 参考dubbo代码:org.apache.dubbo.remoting.transport.netty4.NettyConnectionClient#initBootstrap
            bootstrap.group(loopGroup)
                    .remoteAddress(getConnectAddress())
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ChannelPipeline pipeline = ch.pipeline();
                            // 添加编解码器
                            pipeline.addLast(new StringEncoder());   // 将字符串编码为字节
                            pipeline.addLast(new StringDecoder());   // 将字节解码为字符串
                        }
                    });
            ChannelFuture localhost = bootstrap.connect().sync();
            System.out.println("客户端连接到服务器 127.0.0.1:30888");
            Channel channel = localhost.channel();
            channel.writeAndFlush("Hello, Netty Server!");
            // 等待服务器关闭
            localhost.channel().closeFuture().sync();
        } finally {
            loopGroup.shutdownGracefully();
        }
    }

}

结果验证

启动客户端程序之后,可以看到服务端成功打印客户端发送的请求:

Leave a Reply

Your email address will not be published. Required fields are marked *

目录