美文网首页
Netty UDP 接收缓冲区 报文截取问题

Netty UDP 接收缓冲区 报文截取问题

作者: hdfg159 | 来源:发表于2022-06-05 21:11 被阅读0次

Netty UDP 报文截取问题

问题

  • 最近在写一个 syslog udp 日志接收器,然后发现接收过大的日志数据会被截断,拿到的信息不完整

源码追踪

创建 udp server 的示例代码

       def b = new Bootstrap()
        group = new NioEventLoopGroup()
        b.group(group)
                .channel(NioDatagramChannel.class)
                .localAddress(config.udp.port)
                .handler(new ChannelInitializer<DatagramChannel>() {
                    @Override
                    protected void initChannel(DatagramChannel datagramChannel) throws Exception {
                        ChannelPipeline channelPipeline = datagramChannel.pipeline()
                        channelPipeline.addLast(
                                new UDPSyslogMessageDecoder(),
                                new SyslogMessageHandler()
                        )

                        if (config.log) {
                            channelPipeline.addLast(new SyslogMessageLogHandler())
                        }

                        channelPipeline.addLast(new QianxinLogHandler(vertx,config))
                    }
                })

        startFuture = b.bind().sync()

NioDatagramChannel 初始化源码追踪

channel 使用 NioDatagramChannel ,追踪 NioDatagramChannel 源码

  • 初始化 NioDatagramChannel
    io.netty.channel.socket.nio.NioDatagramChannel.NioDatagramChannel()
    public NioDatagramChannel() {
        this(newSocket(DEFAULT_SELECTOR_PROVIDER));
    }
  • 调用构造方法
    io.netty.channel.socket.nio.NioDatagramChannel#NioDatagramChannel(java.nio.channels.DatagramChannel)
    public NioDatagramChannel(DatagramChannel socket) {
        super(null, socket, SelectionKey.OP_READ);
        config = new NioDatagramChannelConfig(this, socket);
    }
  • 初始化 NioDatagramChannelConfig 配置信息
    io.netty.channel.socket.nio.NioDatagramChannelConfig.NioDatagramChannelConfig
    NioDatagramChannelConfig(NioDatagramChannel channel, DatagramChannel javaChannel) {
        super(channel, javaChannel.socket());
        this.javaChannel = javaChannel;
    }
  • 调用父类构造方法
    io.netty.channel.socket.DefaultDatagramChannelConfig#DefaultDatagramChannelConfig
    public DefaultDatagramChannelConfig(DatagramChannel channel, DatagramSocket javaSocket) {
        // 初始化 2048 字节的固定长度的接收缓冲区
        super(channel, new FixedRecvByteBufAllocator(2048));
        this.javaSocket = ObjectUtil.checkNotNull(javaSocket, "javaSocket");
    }

原因

NioDatagramChannel 默认缓冲区大小只给了 2048 ,开发一个 Syslog UDP 协议服务,日志大小其实就不止这么点,所以日志被截取一部分导致问题出现

解决方法

构建 Bootstrap 增加参数选项,把默认 2048 固定缓冲区调大

实际构建代码如下:

       def b = new Bootstrap()
        group = new NioEventLoopGroup()
        b.group(group)
                .channel(NioDatagramChannel.class)
                .localAddress(config.udp.port)
                // 增加下面这一行代码 固定 64 k大小,这个根据实际情况调整
                .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535))
                .handler(new ChannelInitializer<DatagramChannel>() {
                    @Override
                    protected void initChannel(DatagramChannel datagramChannel) throws Exception {
                        ChannelPipeline channelPipeline = datagramChannel.pipeline()
                        channelPipeline.addLast(
                                new UDPSyslogMessageDecoder(),
                                new SyslogMessageHandler()
                        )

                        if (config.log) {
                            channelPipeline.addLast(new SyslogMessageLogHandler())
                        }

                        channelPipeline.addLast(new QianxinLogHandler(vertx,config))
                    }
                })

        startFuture = b.bind().sync()

相关文章

  • Netty UDP 接收缓冲区 报文截取问题

    Netty UDP 报文截取问题 问题 最近在写一个 syslog udp 日志接收器,然后发现接收过大的日志数据...

  • UDP、可靠性传输及TCP

    UDP 长度字段:在UDP报文段中的字节数(首部加数据)检验和:接收方检查报文段中是否出现了差错,计算时,除了UD...

  • TCP PSH+ACK攻击是什么意思?PSH+ACK攻击原理

    在TCP协议中,到达目的地的报文将进入TCP栈的缓冲区,直到缓冲区满了,报文才被转送给接收系统。此举是为了使系统清...

  • UDP报文收不到问题排查

    一 背景 同事说告警报文没办法接收了, 程序同时向本机发送UDP告警和另外一台机器发送UDP报文,结果显示,本机U...

  • netty自适应缓冲区实现

    netty的自适应缓冲区用于接收从channel读取的数据,且可以动态调整缓冲区大小,减少内存的浪费。当连续两次读...

  • 前端面试题(三)网络篇

    UDP 面向报文 UDP 是一个面向报文(报文可以理解为一段段的数据)的协议。意思就是 UDP 只是报文的搬运工,...

  • 一文讲透前端开发所需网络知识

    UDP 面向报文 UDP 是一个面向报文(报文可以理解为一段段的数据)的协议。意思就是 UDP 只是报文的搬运工,...

  • TCP与UDP协议对比

    TCP与UDP 对比 面向报文的传输方式是应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。发送方...

  • UDP协议浅析

    UDP一次交付一个完整的报文,不会对报文进行拆分。因此,应用程序必须选择合适大小的报文。若报文太长,UDP把它交给...

  • DPDK编程指南(翻译)(六)

    6.报文缓冲区库 报文缓冲区库(Mbuf)提供了申请和释放缓冲区的功能,DPDK应用程序使用这些buffer存储消...

网友评论

      本文标题:Netty UDP 接收缓冲区 报文截取问题

      本文链接:https://www.haomeiwen.com/subject/unfdmrtx.html