首页 > 解决方案 > Netty 4.1 - 检测拒绝连接导致完全连接

问题描述

我已经实现 Netty 4.1 作为 TCP Server 来处理数千个客户端,但不知道如何检测服务器是否无法接收客户端导致连接已满,因此应用程序通知管理员服务器已满,在传统的 ServerSocket 中我们可以检测到异常连接太多/打开的文件太多:

public class TCPServer {
    
    private int port;
    
    public TCPServer (int port) {
        this.port = port;
    }
    
    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast(new FrameDecoder());
                     ch.pipeline().addLast(new ProcessingData());

                 }
             })
             .option(ChannelOption.SO_BACKLOG, 128)         
             .childOption(ChannelOption.SO_KEEPALIVE, true);
            ChannelFuture f = b.bind(port).sync();
    
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
    
    public static void main(String[] args) throws Exception {
        int port = 9812;
        if (args.length > 0) {
            port = Integer.parseInt(args[0]);
        }

        new TCPServer
(port).run();
    }
}

帧解码器也作为检测连接已满

public class FrameDecoder extends ByteToMessageDecoder {

    public FrameDecoder() {
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        try {
            ctx.fireExceptionCaught(cause);
            // i never get exception like too many open files here....
            //
        } catch (Exception ex) {
        }
    }

   @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List<Object> out) throws Exception {
        if (buf.readableBytes() < 5) {
            return;
        }
        int length = 2 + 2; // head and tail

        if (buf.getByte(buf.readerIndex()) == 0x78 && buf.getByte(buf.readerIndex() + 1) == 0x78) {
            length += 1 + buf.getUnsignedByte(buf.readerIndex() + 2);
        } else{
            length += 2 + buf.getUnsignedShort(buf.readerIndex() + 2);
        }

        if (buf.readableBytes() >= length && buf.getUnsignedShort(buf.readerIndex() + length - 2) == 0x0d0a) {
            out.add(buf.readRetainedSlice(length));
            return;
        }
        int endIndex = buf.readerIndex() - 1;
        do {
            endIndex = buf.indexOf(endIndex + 1, buf.writerIndex(), (byte) 0x0d);
            if (endIndex > 0 && buf.writerIndex() > endIndex + 1 && buf.getByte(endIndex + 1) == 0x0a) {
                out.add(buf.readRetainedSlice(endIndex + 2 - buf.readerIndex()));
            }
        } while (endIndex > 0);
    }

}

标签: netty

解决方案


您应该能够ChannelInboundHandlerServerChannelvia添加一个b.handler(...)childHandler(...)为“接受”的Channelshandler(...)添加处理程序,同时为ServerChannel接受s 的添加处理程序Channel。由于抛出异常,ServerChannel您将需要在那里而不是在子处理程序上处理它。


推荐阅读