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

了解netty通道缓冲区和水印

公冶桐
2023-03-14

我试图理解netty缓冲区和水印。

作为一个测试用例,我有一个netty服务器,它向客户端写入数据,客户端被阻塞(每次读取之间的睡眠时间基本上为10秒)

>

它是否正在写入操作系统或TCP缓冲区,netty通道是否也有内部缓冲区?如果是这样,我如何配置它?

我跟踪bytesBeforeUnWritable,但它们似乎没有减少

代码如下:

@Override
    public void channelRead(final ChannelHandlerContext ctx, Object msg) {

        if (server2OutboundChannel.isActive()) {
            if(server2OutboundChannel.isWritable()) {
                server2OutboundChannel.writeAndFlush(msg).addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) {
                        if (future.isSuccess()) {
                            // was able to flush out data, start to read the next chunk
                            //System.out.println(server2OutboundChannel.bytesBeforeUnwritable());
                            ctx.channel().read();
                        } else {
                            future.channel().close();
                        }
                    }
                });
            }else{
                System.out.println("Channel is no longer writeable");
                System.out.println(server2OutboundChannel.bytesBeforeUnwritable());
                System.out.println(server2OutboundChannel.bytesBeforeWritable());
            }
        }
    }

使用端到端源代码重新创建的详细步骤:

>

具体来说,代理代码如下:

<代码>https://github.com/nipunarora/nettyDuplicator/tree/master/src/main/java/org/columbia/parikshan/proxy

>

  • 编译和构建:

    mvn包

    启动服务器

    sh脚本/服务器。sh 3380

    启动netty代理

    sh脚本/nettyProxy.sh-l0.0.0.0:3379-o127.0.0.1:3380

    启动客户端

    sh脚本/客户端。sh 127.0.0.1 3379

    将“hello”作为std输入发送到客户端

    一段时间后发送的netty块和bytesTillUnwritable不会减少。


  • 共有1个答案

    关浩壤
    2023-03-14
    匿名用户

    这些数据在哪里写入?netty的flush()中也会有流量控制吗?

    数据进入了ChannelOutboundBuffer。没有像tcp那样的流控制。数据将保存在ChannelOutboundBuffer中,直到tcp的发送缓冲区中有空间为止。

    它是否正在写入操作系统或TCP缓冲区,netty通道是否也有内部缓冲区?如果是这样,我如何配置它?

    Netty具有ChannelOutboundBuffer,它在将数据发送到操作系统缓冲区之前保留数据。你可以像下面那样配置它。

        Bootstrap bootstrap = new Bootstrap();
        bootstrap.option(ChannelOption.SO_RCVBUF, soRcvBufSize);
        bootstrap.option(ChannelOption.SO_SNDBUF, soSndBufSize);
        bootstrap.option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, writeBufferHighWaterMark);
    

    我跟踪bytesBeforeUnWritable,但它们似乎没有减少

    我编写了一个示例代码,服务器将其写入被阻止的客户端

    您的代理的自动读取为falsenettyproxy前端处理程序#channelRead仅在ctx.channel()时调用。read()(在未来的侦听器中)被调用。监听器将在writeAndFlush完成后调用writeAndFlush将生成一个任务,当消息写入操作系统的缓冲区时,该任务将完成。如果操作系统的缓冲区已填充,则任务将被阻止。netty的缓冲区不可能不可写,它始终是可写的。

    默认的高低水印是什么?我没有在我的应用程序中设置任何东西。有什么方法可以代替它吗?

    您可以在DefaultChannelConfig中检查defualt水印-

     /**
     * Returns {@code true} if and only if the I/O thread will perform the
     * requested write operation immediately.  Any write requests made when
     * this method returns {@code false} are queued until the I/O thread is
     * ready to process the queued write requests.
     */
    boolean isWritable();
    

     类似资料:
    • 默认情况下,通道是不带缓冲区的。 发送端发送数据,同时必须又接收端相应的接收数据。 而带缓冲区的通道则允许发送端的数据发送和接收端的数据获取处于异步状态,就是说发送端发送的数据可以放在缓冲区里面,可以等待接收端去获取数据,而不是立刻需要接收端去获取数据。 不过由于缓冲区的大小是有限的,所以还是必须有接收端来接收数据的,否则缓冲区一满,数据发送端就无法再发送数据了。 package main imp

    • 问题内容: 我正在尝试创建一个异步通道,并且一直在查看http://golang.org/ref/spec#Making_slices_maps_and_channels。 缓冲区大小为10是什么意思?缓冲区大小具体代表/限制了什么? 问题答案: 缓冲区大小是在没有发送阻塞的情况下可以发送到通道的元素数。默认情况下,通道的缓冲区大小为0(可通过来获得此值)。这意味着每个发送都会阻塞,直到另一个go

    • 问题内容: 我是Java的新手。我想做一个游戏。经过大量研究,我不了解缓冲策略的工作原理。.我了解基础知识..它创建了一个屏幕外图像,您以后可以将其放入Windows对象中。 我不知道..我已经研究了很长时间了..根本没有运气..我不知道..也许所有的东西都在里面,而且它很清楚很简单,我我太愚蠢而看不见.. 感谢所有的帮助.. :) 问题答案: 运作方式如下: 该构造了一个当你调用。该知道它属于那

    • 本文向大家介绍详细了解JAVA NIO之Buffer(缓冲区),包括了详细了解JAVA NIO之Buffer(缓冲区)的使用技巧和注意事项,需要的朋友参考一下 当我们需要与 NIO Channel 进行交互时, 我们就需要使用到 NIO Buffer, 即数据从 Buffer读取到 Channel 中, 并且从 Channel 中写入到 Buffer 中。缓冲区本质上是一块可以写入数据,然后可以从

    • 我正在使用Android的类解码MP4 H.264视频,提取每个并尝试转换为RGB,以便我们可以在其他地方使用它。 在从接收到有效的缓冲区索引并获取该之后,我们将使用从JNI获取C代码中的缓冲区,以便在该端进行转换。但是,由于某些原因,当我们重新看到大小值和字节布局时,所看到的缓冲区似乎没有意义。 根据上次返回的,我得到的MediaFormat显然是-下面是完整的MediaFormat字符串。 视

    • 两者都是序列化库,由谷歌开发人员开发。他们之间有什么大的区别吗?将使用协议缓冲区的代码转换为使用FlatBuffers需要大量工作吗?