当前位置: 首页 > 知识库问答 >
问题:

Netty关闭/取消绑定服务器通道

师赤岩
2023-03-14

我对Netty是新手。我使用的是Netty 4.0.28。我指的是《Netty in Action》一书中提供的EchoServer示例。

一切正常。客户端在活动通道上向服务器发送消息,服务器打印接收到的消息并将相同的消息发回客户端。稍后客户端通道关闭,但服务器仍将侦听新连接。

我也想关闭服务器通道并将服务器绑定到新端口。

我应该如何关闭服务器通道?

public class EchoServer {

    private final int port;

    public EchoServer(int port) {
        this.port = port;
    }

    public void start() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(group).channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel ch)
                                throws Exception {
                            ch.pipeline().addLast(new EchoServerHandler());

                        }
                    });
            ChannelFuture f = b.bind().sync();
            System.out.println(EchoServer.class.getName()
                    + " started and listen on " + f.channel().localAddress());

            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        if (args.length != 1) {
            System.err.println("Usage: " + EchoServer.class.getSimpleName()
                    + " <port>");
            return;
        }
        int port = Integer.parseInt(args[0]);
        new EchoServer(port).start();
    }
}


@Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("Server received: " + msg);
        ctx.write(msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(
                ChannelFutureListener.CLOSE);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

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 Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioSocketChannel.class)
                    .remoteAddress(new InetSocketAddress(host, port))
                    .handler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel ch)
                                throws Exception {
                            ch.pipeline().addLast(new EchoClientHandler());

                        }
                    });
            ChannelFuture f = b.connect().sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        if (args.length != 2) {
            System.err.println("Usage: " + EchoClient.class.getSimpleName()
                    + " <host> <port>");
            return;
        }

        final String host = args[0];
        final int port = Integer.parseInt(args[1]);

        new EchoClient(host, port).start();;
    }
}

@Sharable
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ctx.writeAndFlush(Unpooled.copiedBuffer("Netty Rocks!", CharsetUtil.UTF_8));
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg)
            throws Exception {
        System.out.println("Client received: "+ByteBufUtil.hexDump(msg.readBytes(msg.readableBytes())));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

共有1个答案

彭涵衍
2023-03-14

您必须区分“子”通道(可以从处理程序中的“子”通道获得,连接到一个唯一的客户端连接,由“子”通道隐式引用)和“父”通道(可以从“父”通道获得)。

关闭“子项”不会终止f。通道(),因为这是“父”通道(侦听器)。所以你必须做一些类似的事情

ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(
            ChannelFutureListener.CLOSE);
ctx.closeFuture().addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) {
                ctx.channel().parent().close();
        }
});
 类似资料:
  • 我在netty server应用程序中面临资源问题。 无法看到与Netstat的任何打开或挂起的连接... 我使用ReadTimeoutHandler关闭未使用的连接,并使用以下exceptionHandler代码: 服务器引导程序如下所示: 更新2:根据请求,我将日志处理程序移到ReadTimeouthandler前面,以下是日志。客户端通常断开连接的情况: 客户端不断开连接的情况: 所以收盘前

  • 我正在使用netty开发一个代理服务器,我的代理ProxyBackendHandler类如下所示。在channelRead方法中,我需要获取msg数据,并将其作为TextWebSocketFrame写入客户端。为此,我使用了StringBuilder和while循环来迭代ByteBuf。有没有人能给我一个更好的方法来做这件事,因为上面的代码在高数据负载时有很高的性能开销。

  • 有人知道netty服务器处理程序取消从web服务器接收数据的最佳方法吗?我有一个服务器处理程序,它将HttpRequests代理到web服务器。但是,当请求客户端取消请求时,我希望在不关闭服务器处理程序和web服务器之间的连接的情况下停止从web服务器接收服务器通道上的数据。 有谁知道我怎么才能做到这一点。你的答复将不胜感激。 非常感谢。

  • 我有一个基于UDP网络的服务器。它有一个流水线,我在其中重写方法。 我需要时不时地写些信息。我只能通过使用中的套接字信息和中的通道来实现。为了能够重用这些信息,我保留在一个静态映射中。 我做错什么了吗? 有没有比将通道和远程地址保留在某个成员中更好的回写方法?

  • 我在同一个jvm中运行Netty客户端和服务器并试图停止服务器时遇到问题。以下是我的代码来举例说明: 我已经用Netty 3.4.0测试过了。最终和3.4.4。最后,我不知道我做错了什么。 为什么在服务器关闭后,客户端仍然可以向服务器发送数据?