Netty案例(三)之多端口

netty版本

  1. netty版本:io.netty:netty-all:4.1.33.Final

服务端多端口绑定

  1. 服务端单进程多端口绑定,如果要停止某一个端口的监听,一定不能停止EventLoop和Accept线程,单独关闭某一个Channel即可。

        package cn.jannal.netty;
        
        /**
         * 使用telnet 127.0.0.1 6000 测试
         */
        public final class Server {
        
            private EventLoopGroup bossGroup = new NioEventLoopGroup();
            private EventLoopGroup workerGroup = new NioEventLoopGroup();
        
            private ServerBootstrap bootstrap = new ServerBootstrap();
            private ChannelFuture[] ChannelFutures = null;
            private int beginPort = 0;
            private int endPort = 0;
        
            public Server(int beginPort, int endPort) {
                this.beginPort = beginPort;
                this.endPort = endPort;
            }
        
            public static void main(String[] args) {
                Server server = new Server(6000, 8000);
                server.start();
        
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                }
                server.stopServerChannel(6000);
        
            }
        
            public void start() {
                System.out.println("server starting....");
                bootstrap.group(bossGroup, workerGroup);
                bootstrap.channel(NioServerSocketChannel.class);
                bootstrap.childOption(ChannelOption.SO_REUSEADDR, true);
        
                bootstrap.childHandler(new ChannelInitializer() {
                    @Override
                    protected void initChannel(Channel ch) throws Exception {
                        ch.pipeline().addLast(new CountHandler());
                    }
                });
        
                if (ChannelFutures == null) {
                    ChannelFutures = new ChannelFuture[endPort - beginPort + 1];
                }
        
                //多个端口绑定
                for (int i = beginPort; i <= endPort; i++) {
                    final int port = i;
                    ChannelFuture channelFuture = bootstrap.bind(port);
                    ChannelFutures[i - beginPort] = channelFuture;
                    channelFuture.addListener(new GenericFutureListener<Future<? super Void>>() {
                        @Override
                        public void operationComplete(Future<? super Void> future) throws Exception {
                            if (future.isSuccess()) {
                                System.out.println("Started success,port:" + port);
                            } else {
                                System.out.println("Started Failed,port:" + port);
                            }
                        }
                    });
                }
                for (int i = 0; i <= endPort - beginPort; i++) {
                    final Channel channel = ChannelFutures[i].channel();
                    int index = i;
                    channel.closeFuture().addListener(new GenericFutureListener<Future<? super Void>>() {
                        @Override
                        public void operationComplete(Future<? super Void> future) {
                            System.out.println("channel close !");
                            channel.close();
                            ChannelFutures[index] = null;
                        }
                    });
                }
        
            }
        
            public void stopAll() {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
                System.out.println("stoped");
            }
        
            //关闭单个端口的NioServerSocketChannel
            public void stopServerChannel(int port) {
                int i = port - beginPort;
                if (0 <= i && i <= ChannelFutures.length) {
                    if (ChannelFutures != null) {
                        ChannelFutures[i].channel().close();
                    }
                    System.out.println("stoped " + port);
                }
        
            }
        
        }
        
        
        @ChannelHandler.Sharable
        class CountHandler extends ChannelInboundHandlerAdapter {
        
            private AtomicInteger nConnection = new AtomicInteger();
        
            public CountHandler() {
                Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
                    System.out.println("connections: " + nConnection.get());
                }, 0, 2, TimeUnit.SECONDS);
        
            }
        
            @Override
            public void channelActive(ChannelHandlerContext ctx) {
                nConnection.incrementAndGet();
            }
        
            @Override
            public void channelInactive(ChannelHandlerContext ctx) {
                nConnection.decrementAndGet();
            }
        
        }    
    

客户端连接多个服务端端口

  1. 客户端连接多个服务端端口

        public class Client {
        
            private EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
            private Bootstrap bootstrap = new Bootstrap();
            private int startPort;
            private int endPort;
            private String serverHost;
            private ChannelFuture[] ChannelFutures = null;
        
            public Client(int startPort, int endPort, String serverHost) {
                this.startPort = startPort;
                this.endPort = endPort;
                this.serverHost = serverHost;
            }
        
            public static void main(String[] args) throws Exception {
                Client client = new Client(6000, 8000, "127.0.0.1");
                client.start();
            }
        
            public void start() throws Exception {
                bootstrap.group(eventLoopGroup);
                bootstrap.channel(NioSocketChannel.class);
                bootstrap.option(ChannelOption.SO_REUSEADDR, true);
                bootstrap.handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) {
                        ch.pipeline().addLast(new ClientHandler());
                    }
                });
        
                if (ChannelFutures == null) {
                    ChannelFutures = new ChannelFuture[endPort - startPort + 1];
                }
        
                //同时连接多个端口
                for (int i = startPort; i <= endPort; i++) {
                    ChannelFuture channelFuture = bootstrap.connect(new InetSocketAddress(serverHost,i));
                    int port = i;
                    ChannelFutures[i - startPort] = channelFuture;
                    channelFuture.addListener(new GenericFutureListener<Future<? super Void>>() {
                        @Override
                        public void operationComplete(Future<? super Void> future) throws Exception {
                            if (future.isSuccess()) {
                                System.out.println("connect success port : " + port);
                            } else {
                                System.out.println("connect failed port : " + port);
                            }
                        }
                    });
                    Channel channel = channelFuture.channel();
                    channel.closeFuture().addListener(new GenericFutureListener<Future<? super Void>>() {
                        @Override
                        public void operationComplete(Future<? super Void> future) throws Exception {
                            channel.close();
                        }
                    });
                }
            }
        
            public void stop(){
                eventLoopGroup.shutdownGracefully();
                System.out.println("stop");
            }
        
        
            public void closeChannel(int port) {
                int i = port - startPort;
                if (0 <= i && i <= ChannelFutures.length) {
                    if (ChannelFutures != null) {
                        ChannelFutures[i].channel().close();
                    }
                    System.out.println("stoped " + port);
                }
        
            }
        
        }
        
        
        class ClientHandler extends SimpleChannelInboundHandler<String> {
        
            @Override
            public void channelActive(ChannelHandlerContext ctx) {
                ctx.writeAndFlush(Unpooled.copiedBuffer("echo server!\n", CharsetUtil.UTF_8));
            }
        
            //用十六进制记录接收到的消息
            @Override
            public void channelRead0(ChannelHandlerContext ctx, String in) {
                System.out.println(in);
            }
        
            @Override
            public void exceptionCaught(ChannelHandlerContext ctx,
                                        Throwable cause) {
                cause.printStackTrace();
                ctx.close();
            }
        
        }
        
    
    
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Netty 可以在一个服务端开启多个端口,可以通过创建多个 `ServerBootstrap` 对象来实现。具体步骤如下: 1. 创建两个 `EventLoopGroup` 对象,一个用于接收客户端连接,一个用于处理客户端请求。 ```java EventLoopGroup bossGroup = new NioEventLoopGroup(); // 接收客户端连接 EventLoopGroup workerGroup = new NioEventLoopGroup(); // 处理客户端请求 ``` 2. 创建两个 `ServerBootstrap` 对象,分别绑定不同的端口,并设置相应的 `ChannelInitializer`。 ```java // 创建第一个 ServerBootstrap 对象 ServerBootstrap bootstrap1 = new ServerBootstrap(); bootstrap1.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .localAddress(new InetSocketAddress(8080)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { // 添加 ChannelHandler 处理器 ch.pipeline().addLast(new MyChannelHandler1()); } }); // 创建第二个 ServerBootstrap 对象 ServerBootstrap bootstrap2 = new ServerBootstrap(); bootstrap2.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .localAddress(new InetSocketAddress(8081)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { // 添加 ChannelHandler 处理器 ch.pipeline().addLast(new MyChannelHandler2()); } }); ``` 在这里,我们分别创建了两个 `ServerBootstrap` 对象,并分别绑定了 8080 和 8081 端口。同时,我们也设置了相应的 `ChannelInitializer`,来对客户端的请求进行处理。 3. 启动两个 `ServerBootstrap` 对象。 ```java ChannelFuture f1 = bootstrap1.bind().sync(); ChannelFuture f2 = bootstrap2.bind().sync(); ``` 在这里,我们分别启动了两个 `ServerBootstrap` 对象,这时候,这两个服务端就可以分别监听 8080 和 8081 端口了。 4. 关闭服务端。 ```java f1.channel().closeFuture().sync(); f2.channel().closeFuture().sync(); ``` 在这里,我们通过等待两个 `ChannelFuture` 对象的关闭来关闭服务端。完整的示例代码如下: ```java EventLoopGroup bossGroup = new NioEventLoopGroup(); // 接收客户端连接 EventLoopGroup workerGroup = new NioEventLoopGroup(); // 处理客户端请求 // 创建第一个 ServerBootstrap 对象 ServerBootstrap bootstrap1 = new ServerBootstrap(); bootstrap1.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .localAddress(new InetSocketAddress(8080)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { // 添加 ChannelHandler 处理器 ch.pipeline().addLast(new MyChannelHandler1()); } }); // 创建第二个 ServerBootstrap 对象 ServerBootstrap bootstrap2 = new ServerBootstrap(); bootstrap2.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .localAddress(new InetSocketAddress(8081)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { // 添加 ChannelHandler 处理器 ch.pipeline().addLast(new MyChannelHandler2()); } }); // 启动两个 ServerBootstrap 对象 ChannelFuture f1 = bootstrap1.bind().sync(); ChannelFuture f2 = bootstrap2.bind().sync(); // 关闭服务端 f1.channel().closeFuture().sync(); f2.channel().closeFuture().sync(); // 关闭 EventLoopGroup bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值