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

Netty啟動(dòng)步驟綁定端口示例方法源碼分析

 更新時(shí)間:2022年03月25日 11:54:46   作者:向南是個(gè)萬(wàn)人迷  
這篇文章主要介紹了Netty啟動(dòng)步驟綁定端口源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前文傳送門:Netty啟動(dòng)流程注冊(cè)多路復(fù)用源碼解析

綁定端口

上一小節(jié)我們學(xué)習(xí)了channel注冊(cè)在selector的步驟, 僅僅做了注冊(cè)但并沒(méi)有監(jiān)聽(tīng)事件, 事件是如何監(jiān)聽(tīng)的呢?

我們繼續(xù)跟第一小節(jié)的最初的doBind()方法

private ChannelFuture doBind(final SocketAddress localAddress) {
    //初始化并注冊(cè)(1)
    final ChannelFuture regFuture = initAndRegister();
    //獲得channel(2)
    final Channel channel = regFuture.channel();
    if (regFuture.cause() != null) {
        return regFuture;
    }
    if (regFuture.isDone()) {
        ChannelPromise promise = channel.newPromise();
        //綁定(3) 
        doBind0(regFuture, channel, localAddress, promise);
        return promise;
    } else {
        //去除非關(guān)鍵代碼
        return promise;
    }
}

上一小節(jié)跟完了initAndRegister()方法, 我們繼續(xù)往下走:

 第二步, 獲得channel

final Channel channel = regFuture.channel();

通過(guò)ChannelFuture的channel()方法獲得了我們剛剛注冊(cè)的NioServerSocketChannel, 拿到這個(gè)channel我們跟到第三步, 綁定

跟進(jìn)方法doBind0(regFuture, channel, localAddress, promise):

private static void doBind0(final ChannelFuture regFuture, final Channel channel, final SocketAddress localAddress, final ChannelPromise promise) { 
    channel.eventLoop().execute(new Runnable() {
        @Override
        public void run() {
            if (regFuture.isSuccess()) {
                //綁定端口
                channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
            } else {
                promise.setFailure(regFuture.cause());
            }
        }
    });
}

最終會(huì)走到channel.bind(localAddress, promise)這個(gè)方法當(dāng)中

繼續(xù)跟, 會(huì)走到AbstractChannel的bind()方法中:

public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
    //通過(guò)pipeline綁定端口
    return pipeline.bind(localAddress, promise);
}

這里的pipeline就是channel初始化創(chuàng)建的pipline, pipline是事件傳輸通道, 這里我們暫不跟傳輸過(guò)程, 我們只需知道最后這個(gè)方法走到了AbstractChannel的bind()方法

跟到AbstractChannel的bind()方法:

public final void bind(final SocketAddress localAddress, final ChannelPromise promise) {
    //代碼省略
    //端口綁定之前不是active, 返回false
    boolean wasActive = isActive();
    try {
        //做jdk底層的綁定
        doBind(localAddress);
    } catch (Throwable t) {
        //省略
        return;
    }
    //端口綁定之前不是active, 端口綁定之后變成active了
    if (!wasActive && isActive()) {
        invokeLater(new Runnable() {
            @Override
            public void run() {
                pipeline.fireChannelActive();
            }
        });
    }
    safeSetSuccess(promise);
}

重點(diǎn)關(guān)注下doBind(localAddress)方法

跟到NioSeverSocketChannel的doBind()方法:

protected void doBind(SocketAddress localAddress) throws Exception {
    //jdk版本的判斷
    if (PlatformDependent.javaVersion() >= 7) {
        javaChannel().bind(localAddress, config.getBacklog());
    } else {
        javaChannel().socket().bind(localAddress, config.getBacklog());
    }
}

開(kāi)始是一個(gè)jdk版本的判斷, 我們以jdk7以上為例, 看到這條語(yǔ)句:

javaChannel().bind(localAddress, config.getBacklog());

終于找到了和jdk底層相關(guān)的綁定邏輯了, javaChannel()返回的是當(dāng)前channel綁定的jdk底層的channel, 而bind()方法, 就是jdk底層的channel綁定端口的邏輯

回到bind(final SocketAddress localAddress, final ChannelPromise promise)方法:

首先看if判斷: if (!wasActive && isActive()) 

這里意思是如果之前不是active, 綁定之后是active的話, 執(zhí)行if塊, 顯然這里符合條件, 繼續(xù)往里走

最終會(huì)走到這一步, pipeline.fireChannelActive()

這也是傳輸active事件, 目前我們只需知道, 事件完成之后, 會(huì)調(diào)用AbstractChannel內(nèi)部類AbstractUnsafe的beginRead()方法

跟到AbstractUnsafe的beginRead()方法中:

public final void beginRead() {
    assertEventLoop();
    if (!isActive()) {
        return;
    }
    try {
        doBeginRead();
    } catch (final Exception e) {
        //代碼省略
    }
}

我們關(guān)注doBeginRead()方法:

protected void doBeginRead() throws Exception {
    //拿到selectionKey
    final SelectionKey selectionKey = this.selectionKey;
    if (!selectionKey.isValid()) {
        return;
    }
    readPending = true;
    //獲得感興趣的事件
    final int interestOps = selectionKey.interestOps();
    //判斷是不是對(duì)任何事件都不監(jiān)聽(tīng)
    if ((interestOps & readInterestOp) == 0) {
        //此條件成立
        //將之前的accept事件注冊(cè), readInterest代表可以讀取一個(gè)新連接的意思
        selectionKey.interestOps(interestOps | readInterestOp);
    }
}

這里到了jdk底層的調(diào)用邏輯, 通過(guò)注釋不難看出其中的邏輯, 我們拿到和channel綁定的jdk底層的selectionKey, 獲取其監(jiān)聽(tīng)事件, 一上節(jié)我們知道, channel注冊(cè)的時(shí)候沒(méi)有注冊(cè)任何事件, 所以我們這里if  ((interestOps & readInterestOp) == 0) 返回true, 之后, 將accept事件注冊(cè)到channel中, 也就是 selectionKey.interestOps(interestOps | readInterestOp) 這步執(zhí)行的

注冊(cè)完accept事件之后, 就可以輪詢selector, 監(jiān)聽(tīng)是否有新連接接入了

章節(jié)總結(jié)

通過(guò)了這一章的學(xué)習(xí), 我們了解了server啟動(dòng)的大概流程, 這里重點(diǎn)掌握整個(gè)啟動(dòng)脈絡(luò), 知道關(guān)鍵步驟在哪個(gè)類執(zhí)行, 后面的章節(jié)會(huì)分析每一個(gè)模塊的含義

以上就是Netty啟動(dòng)步驟綁定端口源碼分析的詳細(xì)內(nèi)容,更多關(guān)于Netty啟動(dòng)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • mybatis框架入門學(xué)習(xí)教程

    mybatis框架入門學(xué)習(xí)教程

    MyBatis是一個(gè)支持普通SQL查詢,存儲(chǔ)過(guò)程和高級(jí)映射的優(yōu)秀持久層框架。這篇文章主要介紹了mybatis框架入門學(xué)習(xí)教程,需要的朋友可以參考下
    2017-02-02
  • Sping?Security前后端分離兩種實(shí)戰(zhàn)方案

    Sping?Security前后端分離兩種實(shí)戰(zhàn)方案

    這篇文章主要介紹了Sping?Security前后端分離兩種方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Kotlin Coroutines執(zhí)行異步加載示例詳解

    Kotlin Coroutines執(zhí)行異步加載示例詳解

    這篇文章主要給大家介紹了關(guān)于Kotlin Coroutines執(zhí)行異步加載的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • Java中的LinkedHashMap源碼分析

    Java中的LinkedHashMap源碼分析

    這篇文章主要介紹了Java中的LinkedHashMap源碼分析,LinkedHashMap是HashMap的子類,所以基本的操作與hashmap類似,不過(guò)呢,在插入、刪除、替換key-value對(duì)的時(shí)候,需要的朋友可以參考下
    2023-12-12
  • JSR303校驗(yàn)前端傳遞的數(shù)據(jù)方式

    JSR303校驗(yàn)前端傳遞的數(shù)據(jù)方式

    這篇文章主要介紹了JSR303校驗(yàn)前端傳遞的數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 淺談一下Java中的堆和棧

    淺談一下Java中的堆和棧

    這篇文章主要介紹了一下Java中的堆和棧,Java數(shù)據(jù)類型在執(zhí)行過(guò)程中存儲(chǔ)在兩種不同形式的內(nèi)存中:棧和堆,它們通常由運(yùn)行Java虛擬機(jī)(JVM)的底層平臺(tái)維護(hù),需要的朋友可以參考下
    2023-04-04
  • 排序算法圖解之Java快速排序的分步刨析

    排序算法圖解之Java快速排序的分步刨析

    快速排序是通過(guò)一趟排序?qū)⒁判虻臄?shù)據(jù)分割為獨(dú)立的兩個(gè)部分,一部分的所有數(shù)據(jù)比另外一部分的所有數(shù)據(jù)要小,然后按照此方法對(duì)這兩部分分別進(jìn)行快速排序,整個(gè)過(guò)程可以遞歸進(jìn)行,以此達(dá)到整個(gè)數(shù)據(jù)變成有序序列。本文通過(guò)示例講解了快速排序的實(shí)現(xiàn),需要的可以參考一下
    2022-11-11
  • 一文詳解Java中的AuthRequest類(附Demo)

    一文詳解Java中的AuthRequest類(附Demo)

    公共接口,定義了對(duì)第三方平臺(tái)進(jìn)行授權(quán)、登錄、撤銷授權(quán)和刷新 token 的操作,本文將詳細(xì)分析Java中的AuthRequest類(附Demo),文中通過(guò)代碼示例介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下
    2024-04-04
  • Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用

    Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用

    這篇文章主要介紹了Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 在SpringBoot項(xiàng)目中的使用Swagger的方法示例

    在SpringBoot項(xiàng)目中的使用Swagger的方法示例

    這篇文章主要介紹了在SpringBoot項(xiàng)目中的使用Swagger的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05

最新評(píng)論

泾阳县| 商水县| 陆川县| 紫阳县| 固阳县| 乐都县| 习水县| 新津县| 泰顺县| 苍南县| 仁布县| 澄迈县| 湘潭市| 佳木斯市| 上栗县| 双辽市| 五家渠市| 酒泉市| 水城县| 瑞安市| 贺兰县| 莱阳市| 万荣县| 望谟县| 遂川县| 博野县| 资阳市| 绥芬河市| 习水县| 绩溪县| 通渭县| 巴彦淖尔市| 芜湖县| 福海县| 福州市| 炎陵县| 景宁| 舞钢市| 疏附县| 长兴县| 休宁县|