最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Netty客戶端接入流程N(yùn)ioSocketChannel創(chuàng)建解析

 更新時間:2022年03月25日 17:24:27   作者:向南是個萬人迷  
這篇文章主要為大家介紹了Netty客戶端接入流程N(yùn)ioSocketChannel創(chuàng)建源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前文傳送門:Netty客戶端處理接入事件handle創(chuàng)建

NioSocketChannel的創(chuàng)建

回到上一小節(jié)的read()方法

public void read() {
    //必須是NioEventLoop方法調(diào)用的, 不能通過外部線程調(diào)用
    assert eventLoop().inEventLoop();
    //服務(wù)端channel的config
    final ChannelConfig config = config();
    //服務(wù)端channel的pipeline
    final ChannelPipeline pipeline = pipeline();
    //處理服務(wù)端接入的速率
    final RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle();
    //設(shè)置配置
    allocHandle.reset(config);
    boolean closed = false;
    Throwable exception = null;
    try {
        try {
            do {
                //創(chuàng)建jdk底層的channel
                //readBuf用于臨時承載讀到鏈接
                int localRead = doReadMessages(readBuf);
                if (localRead == 0) {
                    break;
                }
                if (localRead < 0) {
                    closed = true;
                    break;
                }
                //分配器將讀到的鏈接進(jìn)行計(jì)數(shù)
                allocHandle.incMessagesRead(localRead);
                //連接數(shù)是否超過最大值
            } while (allocHandle.continueReading());
        } catch (Throwable t) {
            exception = t;
        }
        int size = readBuf.size();
        //遍歷每一條客戶端連接
        for (int i = 0; i < size; i ++) {
            readPending = false;
            //傳遞事件, 將創(chuàng)建NioSokectChannel進(jìn)行傳遞
            //最終會調(diào)用ServerBootstrap的內(nèi)部類ServerBootstrapAcceptor的channelRead()方法
            pipeline.fireChannelRead(readBuf.get(i));
        }
        readBuf.clear();
        allocHandle.readComplete();
        pipeline.fireChannelReadComplete();
        //代碼省略
    } finally {
        //代碼省略
    }
}

我們繼續(xù)剖析int localRead = doReadMessages(readBuf)這一部分邏輯

我們首先看readBuf

private final List<Object> readBuf = new ArrayList<Object>();

這里只是簡單的定義了一個ArrayList, doReadMessages(readBuf)方法就是將讀到的鏈接放在這個list中, 因?yàn)檫@里是NioServerSocketChannel所以這走到了NioServerSocketChannel的doReadMessage()方法

跟到doReadMessage()方法中:

protected int doReadMessages(List<Object> buf) throws Exception {
    //根據(jù)當(dāng)前jdk底層的serverSocketChannel拿到j(luò)dk底層channel
    SocketChannel ch = javaChannel().accept();
    try {
        if (ch != null) {
            //封裝成一個NioSokectChannel扔到buf中
            buf.add(new NioSocketChannel(this, ch));
            return 1;
        }
    } catch (Throwable t) {
        //代碼省略
    }
    return 0;
}

jdk底層相關(guān)的內(nèi)容

首先根據(jù)jdk的ServerSocketChannel拿到j(luò)dk的Channel, 熟悉Nio的小伙伴應(yīng)該不會陌生

封裝成一個NioSokectChannel扔到Readbuf中

這里的NioSocketChannel是對jdk底層的SocketChannel的包裝, 我們看到其構(gòu)造方法傳入兩個參數(shù), this代表當(dāng)前NioServerSocketChannel, ch代表jdk的SocketChannel

我們跟到NioSocketChannel的構(gòu)造方法中:

public NioSocketChannel(Channel parent, SocketChannel socket) {
    super(parent, socket);
    config = new NioSocketChannelConfig(this, socket.socket());
}

這里看到調(diào)用了父類構(gòu)造方法, 傳入兩個參數(shù), parent代表創(chuàng)建自身channel的, NioServerSocketChannel, socket代表jdk底層的socketChannel

跟到父類構(gòu)造方法中

protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) { 
    super(parent, ch, SelectionKey.OP_READ);
}

其中SelectionKey.OP_READ代表其監(jiān)聽事件是讀事件

繼續(xù)跟父類的構(gòu)造方法:

protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
    super(parent);
    this.ch = ch;
    this.readInterestOp = readInterestOp;
    try {
        //設(shè)置為非阻塞
        ch.configureBlocking(false);
    } catch (IOException e) {
        //代碼省略
    }
}

這里初始化了自身成員變量ch, 就是jdk底層的SocketChannel, 并初始化了自身的監(jiān)聽事件readInterestOp, 也就是讀事件

ch.configureBlocking(false)這一步熟悉nio的小伙伴也不陌生, 就是將jdk的SocketChannel設(shè)置為非阻塞

我們繼續(xù)跟到父類構(gòu)造方法中:

protected AbstractChannel(Channel parent) {
    this.parent = parent;
    id = newId();
    unsafe = newUnsafe();
    pipeline = newChannelPipeline();
}

這里初始化parent, 也就是創(chuàng)建自身的NioServerSocketChannel, 并為自身創(chuàng)建了唯一id

初始化unsafe, 我們跟到newUnsafe()方法中

由于此方法是NioEventLoop調(diào)用的, 所以會走到其父類AbstractNioByteChannel的newUnsafe()

跟到newUnsafe()中:

protected AbstractNioUnsafe newUnsafe() {
    return new NioByteUnsafe();
}

這里創(chuàng)建了NioByteUnsafe對象, 所以NioSocketChannel對應(yīng)的unsafe是NioByteUnsafe

繼續(xù)往下跟, 我們看到其初始化了pipeline, 有關(guān)pipline的知識, 我們會在下一章節(jié)中講到

回到NioSocketChannel中的構(gòu)造方法:

public NioSocketChannel(Channel parent, SocketChannel socket) {
    super(parent, socket);
    config = new NioSocketChannelConfig(this, socket.socket());
}

同NioServerSocketChannel一樣, 這里也初始化了一個Config屬性, 傳入兩個參數(shù), 當(dāng)前NioSocketChannel自身和jdk的底層SocketChannel的socket對象

我們跟進(jìn)其構(gòu)造方法

private NioSocketChannelConfig(NioSocketChannel channel, Socket javaSocket) {
    super(channel, javaSocket);
}

同樣, 這個類是NioSocketChannel的內(nèi)部類

繼續(xù)跟父類構(gòu)造方法:

public DefaultSocketChannelConfig(SocketChannel channel, Socket javaSocket) {
    super(channel);
    if (javaSocket == null) {
        throw new NullPointerException("javaSocket");
    }
    //保存當(dāng)前javaSocket
    this.javaSocket = javaSocket;
    //是否禁止Nagle算法
    if (PlatformDependent.canEnableTcpNoDelayByDefault()) {
        try {
            setTcpNoDelay(true);
        } catch (Exception e) {
        }
    }
}

這里保存了SocketChannel的socket對象, 并且默認(rèn)的情況禁止了Nagle算法, 有關(guān)Nagle, 感興趣的同學(xué)可以學(xué)習(xí)下相關(guān)知識

繼續(xù)跟到父類構(gòu)造方法中:

public DefaultChannelConfig(Channel channel) {
    this(channel, new AdaptiveRecvByteBufAllocator());
}

又跟到到了我們熟悉的部分了, 也就是說, 無論NioServerSocketChannel和NioSocketChannel, 最后都會初始化DefaultChannelConfig, 并創(chuàng)建可變ByteBuf分配器, 我們之前小節(jié)對此做過詳細(xì)剖析這里不再贅述, 這部分忘記的內(nèi)容可以閱讀之前小節(jié)內(nèi)容進(jìn)行回顧

這個分配器什么時候真正分配字節(jié)緩沖的呢?我們會在之后的章節(jié)進(jìn)行詳細(xì)剖析

至此我們剖析完成了NioSocketChannel的初始化過程

以上就是Netty客戶端接入流程N(yùn)ioSocketChannel創(chuàng)建源碼解析的詳細(xì)內(nèi)容,更多關(guān)于Netty客戶端接入流程N(yùn)ioSocketChannel的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 簡單了解Java多線程實(shí)現(xiàn)的四種方式

    簡單了解Java多線程實(shí)現(xiàn)的四種方式

    這篇文章主要介紹了簡單了解Java多線程實(shí)現(xiàn)的四種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Reactive反應(yīng)式編程及使用介紹

    Reactive反應(yīng)式編程及使用介紹

    這篇文章主要介紹了為什使用Reactive反應(yīng)式編程的原因分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進(jìn)步,早日升職加薪
    2022-02-02
  • springboot框架阿里開源低代碼工具LowCodeEngine

    springboot框架阿里開源低代碼工具LowCodeEngine

    這篇文章主要為大家介紹了springboot框架阿里開源低代碼LowCodeEngine工具使用詳解有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 詳解如何使用SpringBoot封裝Excel生成器

    詳解如何使用SpringBoot封裝Excel生成器

    在軟件開發(fā)過程中,經(jīng)常需要生成Excel文件來導(dǎo)出數(shù)據(jù)或者生成報(bào)表,為了簡化開發(fā)流程和提高代碼的可維護(hù)性,我們可以使用Spring Boot封裝Excel生成器,本文將介紹如何使用Spring Boot封裝Excel生成器,并提供一些示例代碼來說明其用法和功能
    2023-06-06
  • Mybatis基于xml配置實(shí)現(xiàn)單表的增刪改查功能

    Mybatis基于xml配置實(shí)現(xiàn)單表的增刪改查功能

    這篇文章主要介紹了Mybatis基于xml配置實(shí)現(xiàn)單表的增刪改查,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Spring定時任務(wù)注解@Scheduled詳解

    Spring定時任務(wù)注解@Scheduled詳解

    這篇文章主要介紹了Spring定時任務(wù)注解@Scheduled詳解,@Scheduled注解是包org.springframework.scheduling.annotation中的一個注解,主要是用來開啟定時任務(wù),本文提供了部分實(shí)現(xiàn)代碼與思路,需要的朋友可以參考下
    2023-09-09
  • Java數(shù)據(jù)結(jié)構(gòu)常見幾大排序梳理

    Java數(shù)據(jù)結(jié)構(gòu)常見幾大排序梳理

    Java常見的排序算法有:直接插入排序、希爾排序、選擇排序、冒泡排序、歸并排序、快速排序、堆排序等。本文詳解介紹它們的實(shí)現(xiàn)以及圖解,需要的可以參考一下
    2022-03-03
  • java通過url下載文件并輸出的方法

    java通過url下載文件并輸出的方法

    下面小編就為大家分享一篇java通過url下載文件并輸出的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • Java如何實(shí)現(xiàn)可折疊Panel方法示例

    Java如何實(shí)現(xiàn)可折疊Panel方法示例

    這篇文章主要給大家介紹了關(guān)于利用Java如何實(shí)現(xiàn)可折疊Panel的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • 通過Java壓縮JavaScript代碼實(shí)例分享

    通過Java壓縮JavaScript代碼實(shí)例分享

    這篇文章主要介紹了通過Java壓縮JavaScript代碼實(shí)例分享,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-12-12

最新評論

芒康县| 汝州市| 玉溪市| 浦东新区| 苗栗县| 松溪县| 安岳县| 五莲县| 会东县| 池州市| 乳源| 朝阳市| 慈溪市| 柳河县| 策勒县| 林芝县| 喀什市| 张家港市| 泗洪县| 长武县| 东兰县| 上栗县| 多伦县| 巨野县| 长岭县| 苍梧县| 调兵山市| 綦江县| 若羌县| 忻城县| 龙陵县| 安庆市| 云林县| 即墨市| 陆良县| 宁波市| 嘉兴市| 海宁市| 石楼县| 昌黎县| 崇文区|