zoukankan      html  css  js  c++  java
  • Netty源码剖析-发送数据

    参考文献:极客时间傅健老师的《Netty源码剖析与实战》Talk is cheap.show me the code!

      开始之前先介绍下Netty写数据的三种方式:

        ①:write:写到一个buffer,flush:把buffer里的数据发送出去

        ②:writeAndFlush:写到buffer,立马发送

        ③:write和flush之间有个ChannelOutboundBuffer

     可以用生活中快递场景来类比下:

      write相当于揽收到仓库,flush相当于从仓库发货,writeAndFlush相当于揽收到仓库立马就发货(类似加急件),ChannelOutboundBuffer相当于揽收和发货之间有个缓冲的仓库

    ----主线:如图:

      

    ----2源码演示:

      在channelRead()加入断点,启动服务端和客户端

    开始跟进ctx.write();一直跟下回来到:

    然后继续跟进invokeWrte();

     然后跟进invokeWrite0();

     再继续跟进write(),一步一步则会进入到这:

     上图代码执行的地方就相当于发快递的仓库这一步骤;继续往下走则能看到:

     可以简单进去看一看:

    它是添加到队尾;接着继续下边的“incrementPendingOutboundBytes()”;

     

    判断待发送的数据的size是否高于高水位线,如果高于则修改为不可写状态。然后跳出来,write()完成之后开始发送了:在发送的地方加一个断点:

     套路一样:

     然后找到flush()

     再继续跟进:

    addFlush()就表示要装车发货了,跟进看看:

    它的意思就是把unflushedEntry里面的数据转Flush里面去。然后跳回去:

    进入flush0();

     

    进入doWrite();

     挨个走就是调用jdk的实现

    ----3总结:

      写的本质:

          -single write:sun.nio.ch.SocketChannelImpl#write(java.nio.ByteBuffer)(单个写)

          -gathering write:sun.nio.ch.SocketChannelImpl#write(java.nio.ByteBuffer[],int,int)(批量写)

      写数据写不进去时,会停止写,注册一个OP_WRITE事件,来通知什么时候可以写进去

      OP_WRITE不是说有数据可写,而是说可以写进去,所以正常情况,不能注册,否则一直触发

      批量写数据时,如果尝试写的都写进去了,接下来会尝试写更多(maxBytesPerGatheringWrite)。

      只要有数据要写,且能写,则一直尝试,直到16次(writeSpinCount),写16次还没有写完,就直接schedule一个task来继续写,而不是用注册写事件来触发,更简洁有力。

      待写数据太多,超过一定的水位线(writeBufferWaterMark.high()),会将可写的标志位改成false,让应用端自己做决定要不要继续写。

      channelHandlerContext.channel().write():从TailContext开始执行;  

      channelHandlerContext.write():从当前的Context开始。

    我只想做的更好,仅此而已。

  • 相关阅读:
    有是JSF的一个小问题,搞了我两天!从周五到周二
    MyFaces Tree2控件使用 From http://blog.163.com/net_wood/blog
    使用JSF的Selectonemenu
    SSO摘抄
    用于快速将 Web 应用程序集成到 WebSphere Portal 中的选项
    Lua 公历转农历算法
    编程语言适用场合。。。
    了解grep、vim的查找 和正则表达式
    程序员知识资产的投资
    铁道部新客票系统设计(一)
  • 原文地址:https://www.cnblogs.com/-qilin/p/11819990.html
Copyright © 2011-2022 走看看