<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jack Jiang

    我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
    posts - 494, comments - 13, trackbacks - 0, articles - 1

    原作者江成軍,原題“還在被Java NIO虐?該試試Netty了”,收錄時有修訂和改動。

    1、閱讀對象

    本文適合對Netty一無所知的Java NIO網絡編程新手閱讀,為了做到這一點,內容從最基本介紹到開發環境的配置,再到第一個Demo代碼的編寫,事無巨細都用詳細的圖文進行了說明。

    所以本文這對于新手來說幫助很大,但對于老司機來說,就沒有必要了。老司機請繞道哦。

    PS:是的,用Java寫IM、消息推送的話,基本上都是用的Netty,所以如果你想用Java做即時通訊這類系統,學習Netty肯定沒錯。

    學習交流:

    - 即時通訊/推送技術開發交流5群:215477170[推薦]

    - 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

    - 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK

    (本文同步發布于:http://www.52im.net/thread-3207-1-1.html

    2、本文作者

    江成軍:工信部信息系統項目管理師,全棧工程師,多年豐富的JavaWEB平臺、PC端軟件、移動端APP開發及培訓經驗,擅長把復雜的事情搞簡單。

    3、基本常識

    在了解Netty之前,我們非常有必要簡要了解一下Java網絡編程模型的基本常識,具體說也就是BIO、NIO和AIO這3個技術概念。

    BIO、NIO和AIO這三個概念分別對應三種通訊模型:阻塞、非阻塞、非阻塞異步,具體這里就不詳細寫了。網上好多博客說Netty對應NIO,準確來說,應該是既可以是NIO,也可以是AIO,就看你怎么實現。

    這三個概念的區別如下:

    • 1)BIO:一個連接一個線程,客戶端有連接請求時服務器端就需要啟動一個線程進行處理,線程開銷大。
    • 2)NIO:一個請求一個線程,客戶端發送的連接請求會注冊到多路復用器上,多路復用器輪詢到該連接有I/O請求時才啟動一個線程進行處理;
    • 3)AIO:一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啟動線程進行處理。

    通俗地概括一下就是:

    • 1)BIO是面向流的,NIO是面向緩沖區的;
    • 2)BIO的各種流是阻塞的,而NIO是非阻塞的;
    • 3)BIO的Stream是單向的,而NIO的channel是雙向的。

    NIO的的顯著特點:事件驅動模型、單線程處理多任務、非阻塞I/O,I/O讀寫不再阻塞,而是返回0、基于block的傳輸比基于流的傳輸更高效、更高級的IO函數zero-copy、IO多路復用大大提高了Java網絡應用的可伸縮性和實用性?;赗eactor線程模型。

    限于篇幅原因,這里沒辦法深入展開話題,想深入了解的,可以繼續閱讀這幾篇:

    4、認識Netty

    4.1 基本介紹

    Netty是一個Java NIO技術的開源異步事件驅動的網絡編程框架,用于快速開發可維護的高性能協議服務器和客戶端。

    往通俗了講,可以將Netty理解為:一個將Java NIO進行了大量封裝,并大大降低Java NIO使用難度和上手門檻的超牛逼框架。

    PS:Netty的官網是 https://netty.io/,可以隨時下載到最新的Netty源碼,以及各種API文檔和開發指南。

    4.2 技術特征

    Netty的優點,概括一下就是:

    • 1)使用簡單;
    • 2)功能強大;
    • 3)性能強悍。

    Netty的特點:

    • 1)高并發:基于 NIO(Nonblocking IO,非阻塞IO)開發,對比于 BIO(Blocking I/O,阻塞IO),他的并發性能得到了很大提高;
    • 2)傳輸快:傳輸依賴于零拷貝特性,盡量減少不必要的內存拷貝,實現了更高效率的傳輸;
    • 3)封裝好:封裝了 NIO 操作的很多細節,提供了易于使用調用接口。

    Netty的優勢:

    • 1)使用簡單:封裝了 NIO 的很多細節,使用更簡單;
    • 2)功能強大:預置了多種編解碼功能,支持多種主流協議;
    • 3)擴展性強:可以通過 ChannelHandler 對通信框架進行靈活地擴展;
    • 4)性能優異:通過與其他業界主流的 NIO 框架對比,Netty 的綜合性能最優;
    • 5)運行穩定:Netty 修復了已經發現的所有 NIO 的 bug,讓開發人員可以專注于業務本身;
    • 6)社區活躍:Netty 是活躍的開源項目,版本迭代周期短,bug 修復速度快。

    Netty高性能表現在哪些方面?

    • 1)IO 線程模型:同步非阻塞,用最少的資源做更多的事;
    • 2)內存零拷貝:盡量減少不必要的內存拷貝,實現了更高效率的傳輸;
    • 3)內存池設計:申請的內存可以重用,主要指直接內存。內部實現是用一顆二叉查找樹管理內存分配情況;
    • 4)串形化處理讀寫:避免使用鎖帶來的性能開銷;
    • 5)高性能序列化協議:支持 protobuf 等高性能序列化協議。

    限于篇幅,Netty的詳細特征就不展開了,有興趣的可以讀一讀《新手入門:目前為止最透徹的的Netty高性能原理和框架架構解析》。

    5、Netty的作者

    個人而言,了解一項技術,比較喜歡扒一下它的作者情況,不是八卦,只是個人習慣,希望對所使用的技術了解地更多更全面而已。

    5.1 Netty的創始人

    Netty的創始人是韓國人Trustin Lee,80年出生,8歲起在MSX迷你計算機上編寫BASIC程序,愛好游戲編程以及使用匯編、C和C++解決編程問題,1998年獲得韓國信息奧林匹克競賽銅牌。

    就讀于韓國Yonsei大學計算機系期間,曾為多家公司編寫高性能網絡應用以及少量的web程序,畢業后,就職于Arreo通訊公司,該公司為韓國最大的移動短信提供商之一。

    他現在韓國line公司工作(據他個人博客顯示,他以于2020年8月底從Line離職了,具體博文 點這里),早前應用較多的Mina也是這牛人的作品。

    ▲ Trustin Lee 本尊

    Trustin Lee大神的其它信息:

    5.2 Netty現任Leader

    Netty目前的項目leader是德國人Norman Maurer(之前在Redhat,全職開發Netty),也是《Netty in Action》的作者,目前是蘋果公司高級工程師。

    ▲ Norman maurer 本尊

    Norman maurer大神的其它信息:

    最后,附上兩位大神的同框圖:

    6、Netty能做什么?

    學技能都是為了能夠應用到實際工作中去,誰也不是為了學而學、弄著玩不是,那么Netty能做什么呢?

    主要是在兩個方面。

    一方面:現在物聯網的應用無處不在,大量的項目都牽涉到應用傳感器和服務器端的數據通信,Netty作為基礎通信組件、能夠輕松解決之前有較高門檻的通信系統開發,你不用再為如何解析各類簡單、或復雜的通訊協議而薅頭發了,有過這方面開發經驗的程序員會有更深刻、或者說刻骨銘心的體會。

    另一方面:現在互聯網系統講究的都是高并發、分布式、微服務,各類消息滿天飛(是的,IM系統、消息推送系統就是其中的典型),Netty在這類架構里面的應用可謂是如魚得水,如果你對當前的各種應用服務器不爽,那么完全可以基于Netty來實現自己的HTTP服務器、FTP服務器、UDP服務器、RPC服務器、WebSocket服務器、Redis的Proxy服務器、MySQL的Proxy服務器等等。

    7、掌握Netty有什么好處?

    直接的好處是:能夠有進大廠、拿高薪的機會,業內好多著名的公司在招聘高級/資深Java工程師時基本上都要求熟練掌握、或熟悉Netty。

    這個名單還可以很長很長。。。

    作為一個學Java的,如果沒有研究過Netty,那么你對Java語言的使用和理解僅僅停留在表面水平,會點SSH,寫幾個MVC,訪問數據庫和緩存,這些只是初、中等Java程序員干的事。如果你要進階,想了解Java服務器的深層高階知識,Netty絕對是一個必須要過的門檻。

    間接地好處是:多款開源框架中應用了Netty,掌握了Netty,就具有分析這些開源框架的基礎了,也就是有了成為技術大牛的基礎。

    這些開源框架有哪些呢?

    簡單羅列一些典型的,如下:

    • 1)阿里分布式服務框架 Dubbo 的 RPC 框架;
    • 2)淘寶的消息中間件 RocketMQ;
    • 3)Hadoop 的高性能通信和序列化組件 Avro 的 RPC 框架;
    • 4)開源集群運算框架 Spark;
    • 5)分布式計算框架 Storm
    • 6)并發應用和分布式應用 Akka
    • 7)名單依然很長很長。。。。

    8、理論知識準備

    本文的下半部分,將手翅手,帶你動手實現一個傳輸字符串的簡單實例。

    在開始動手之前,必要的基礎概念還是要知道的,要不然代碼敲下來,功能倒是實現了,但對Netty還是一頭霧水,這就不是本文要達到的目的了。

    本示例需要用到的基礎知識主要有以下幾方面的東東,這些知識點最好有一個大概的了解,要不然,看實例會有一定的困難。

    • 1)掌握Java基礎;
    • 2)掌握Maven基礎;
    • 3)熟悉IntelliJ IDEA集成開發工具的使用,這個工具簡稱IDEA;
    • 4)知道TCP、Socket的基本概念。

    尤其提一下,TCP、Socket沒概念的,下面這幾篇一定要讀一下:

    大致了解一下Netty的主要組件及概念:

    • 1)I/O:各種各樣的流(文件、數組、緩沖、管道。。。)的處理(輸入輸出);
    • 2)Channel:通道,代表一個連接,每個Client請對會對應到具體的一個Channel;
    • 3)ChannelPipeline:責任鏈,每個Channel都有且僅有一個ChannelPipeline與之對應,里面是各種各樣的Handler;
    • 4)handler:用于處理出入站消息及相應的事件,實現我們自己要的業務邏輯;
    • 5)EventLoopGroup:I/O線程池,負責處理Channel對應的I/O事件;
    • 6)ServerBootstrap:服務器端啟動輔助對象;
    • 7)Bootstrap:客戶端啟動輔助對象;
    • 8)ChannelInitializer:Channel初始化器;
    • 9)ChannelFuture:代表I/O操作的執行結果,通過事件機制,獲取執行結果,通過添加監聽器,執行我們想要的操作;
    • 10)ByteBuf:字節序列,通過ByteBuf操作基礎的字節數組和緩沖區。

    關于深入理解Netty的這些概念,建議有必要的話,務必詳讀:新手入門:目前為止最透徹的的Netty高性能原理和框架架構解析》。

    對于Netty開發,API文檔和源碼是最常用的資料,以下是我整理的在線閱讀鏈接:

    9、開發環境準備

    開發環境準備主要有三個方面:JDK安裝及環境變量設置、Maven安裝及環境變量設置、IDEA安裝及基本設置。

    下面請逐個跟著我來傻瓜式配置和操做即可。

    9.1 JDK安裝及環境變量設置

    JDK下載,可以從官方現在,也可以度娘上隨便搜下載鏈接,我這里下載的是JDK8,要注意一點的是,現在從JDK的官網Oracle下載需要賬號了,沒賬號的可下不了啦,不知道在搞什么東東。

    官網下載地址:https://www.oracle.com ,截圖依次如下:

    下載完,一路Next安裝完,在創建Java環境變量設置,[此電腦]右鍵-->[屬性]-->[高級系統設置]-->[環境變量]-->[系統變量]。

    截圖如下:

    Java環境變量創建完畢后,在DOS窗口執行命令:java -version,測試一下是否正常

    9.2 Maven安裝及環境變量設置

    Maven功能很強大,但大家不用擔心、本實例中僅僅是利用其便利的jar包依賴、jar包依賴傳遞,基本上沒有任何學習成本。

    jar包依賴、jar包依賴傳遞的概念如下圖,清楚明了,都不用多做解釋:

    Maven是下載,解壓縮后,配置環境變量后就能用,不用安裝的。

    下載地址:https://downloads.apache.org/maven/maven-3/3.6.3/binaries/

    安裝:下載壓縮包,解壓,文件夾拷貝到所想存儲的位置(如C盤根目錄)。

    配置環境變量,和Java的環境變量配置一樣的,創建MAVEN_HOME,指向Maven文件夾,再在path中添加進去就行。

    如下圖:

    由于直接沖Maven的中央倉庫中自動下載jar包較慢,一般在Maven的配置文件中,增加阿里云的公共倉庫配置,這樣會顯著加快jar包的下載速度。

    如下圖所示:

    上面的環境變量設置完后,通過DOS窗口中輸入命令:mvn -version 進行驗證是否成功,如下:

    9.3 IDEA安裝及基本設置

    IDEA的下載和安裝就不多說了,其版本分旗艦版和社區版,旗艦版收費,社區版免費,社區版不支持html、js、css等。

    但對于本實例,社區版就夠用了,但如果你不在乎那點銀子,可以考慮旗艦版,一步到位,萬一后面我們還要做WEB系統開發可以免得折騰。

    其安裝不用多說,一路Next就行,安裝完后,在其配置里面指定一下JDK、Maven的位置就行了,如下圖依次所示。

    Maven指定:[File]-->[setting]-->[Build,Excution,Deployment]-->[Build Tools]-->[Maven]

    JDK指定:[File]-->[Project Structure]-->[Project Setting]-->[Project]

    9.4 在IDEA中創建Maven工程

    新建工程:

    填寫包名及工程名稱:

    Maven配置:

    生成工程,自動創建Maven的依賴文件:

    在pom.xml中配置Netty依賴:

    經過上面的步驟,我們的Maven工程就已經創建完畢,現在可以編寫Netty的第一個程序,這個程序很簡單,傳輸一個字符串,雖然程序很簡單,但是已經能夠大體上反映Netty開發通信程序的一個整體流程了。

    10、開始動手代碼實戰

    10.1 Netty開發的基本套路

    Netty開發的基本套路很簡潔,服務器端和客戶端都是這樣。

    大致的套路基本如下:

    Netty開發的實際代碼過程,也確實并不復雜,就像下圖這樣,綠色的代表客戶端流程、藍色的代表服務器端流程,注意標紅的部分。

    實際代碼過程就像下圖這樣:

    10.2 創建客戶端類

    10.2.1)創建Handler:

    首先創建Handler類,該類用于接收服務器端發送的數據,這是一個簡化的類,只重寫了消息讀取方法channelRead0、捕捉異常方法exceptionCaught。

    客戶端的Handler一般繼承的是SimpleChannelInboundHandler,該類有豐富的方法,心跳、超時檢測、連接狀態等等。

    代碼如下:

    import io.netty.buffer.ByteBuf;

    import io.netty.channel.ChannelHandler;

    import io.netty.channel.ChannelHandlerContext;

    import io.netty.channel.SimpleChannelInboundHandler;

    import io.netty.util.CharsetUtil;

    /**

     * @Date: 2020/6/1 11:12

     * @Description: 通用handler,處理I/O事件

     */

    @ChannelHandler.Sharable

    public class HandlerClientHello extends SimpleChannelInboundHandler<ByteBuf>

    {

        @Override

        protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception

        {

            /**

            * @Description  處理接收到的消息

            **/

            System.out.println("接收到的消息:"+byteBuf.toString(CharsetUtil.UTF_8));

        }

     

        @Override

        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throwsException

        {

            /**

            * @Description  處理I/O事件的異常

            **/

            cause.printStackTrace();

            ctx.close();

        }

    }

    代碼說明:

    • 1)@ChannelHandler.Sharable:這個注解是為了線程安全,如果你不在乎是否線程安全,不加也可以;
    • 2)SimpleChannelInboundHandler:這里的類型可以是ByteBuf,也可以是String,還可以是對象,根據實際情況來;
    • 3)channelRead0:消息讀取方法,注意名稱中有個0;
    • 4)ChannelHandlerContext:通道上下文,代指Channel;
    • 5)ByteBuf:字節序列,通過ByteBuf操作基礎的字節數組和緩沖區,因為JDK原生操作字節麻煩、效率低,所以Netty對字節的操作進行了封裝,實現了指數級的性能提升,同時使用更加便利;
    • 6)CharsetUtil.UTF_8:這個是JDK原生的方法,用于指定字節數組轉換為字符串時的編碼格式。

    10.2.2)創建客戶端啟動類:

    客戶端啟動類根據服務器端的IP和端口,建立連接,連接建立后,實現消息的雙向傳輸。

    代碼較簡潔,如下:

    import com.sun.org.apache.bcel.internal.generic.ATHROW;

    import io.netty.*;

    import java.net.InetSocketAddress;

     

    /**

     * @Date: 2020/6/1 11:24

     * @Description: 客戶端啟動類

     */

    public class AppClientHello

    {

        private final String host;

        private fina lint port;

     

        public AppClientHello(String host, int port)

        {

            this.host = host;

            this.port = port;

        }

     

        public void run() throws Exception

        {

            /**

            * @Description  配置相應的參數,提供連接到遠端的方法

            **/

            EventLoopGroup group = newNioEventLoopGroup();//I/O線程池

            try{

                Bootstrap bs = newBootstrap();//客戶端輔助啟動類

                bs.group(group)

                        .channel(NioSocketChannel.class)//實例化一個Channel

                        .remoteAddress(newInetSocketAddress(host,port))

                        .handler(newChannelInitializer<SocketChannel>()//進行通道初始化配置

                        {

                            @Override

                            protected void initChannel(SocketChannel socketChannel) throws Exception

                            {

                                socketChannel.pipeline().addLast(newHandlerClientHello());//添加我們自定義的Handler

                            }

                        });

     

                //連接到遠程節點;等待連接完成

                ChannelFuture future=bs.connect().sync();

     

                //發送消息到服務器端,編碼格式是utf-8

                future.channel().writeAndFlush(Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8));

     

                //阻塞操作,closeFuture()開啟了一個channel的監聽器(這期間channel在進行各項工作),直到鏈路斷開

                future.channel().closeFuture().sync();

     

            } finally{

                group.shutdownGracefully().sync();

            }

        }

     

        public static void main(String[] args) throws Exception

        {

            new AppClientHello("127.0.0.1",18080).run();

        }

    }

    由于代碼中已經添加了詳盡的注釋,這里只對極個別的進行說明:

    • 1)ChannelInitializer:通道Channel的初始化工作,如加入多個handler,都在這里進行;
    • 2)bs.connect().sync():這里的sync()表示采用的同步方法,這樣連接建立成功后,才繼續往下執行;
    • 3)pipeline():連接建立后,都會自動創建一個管道pipeline,這個管道也被稱為責任鏈,保證順序執行,同時又可以靈活的配置各類Handler,這是一個很精妙的設計,既減少了線程切換帶來的資源開銷、避免好多麻煩事,同時性能又得到了極大增強。

    10.3 創建服務器端類

    10.3.1)創建Handler:

    和客戶端一樣,只重寫了消息讀取方法channelRead(注意這里不是channelRead0)、捕捉異常方法exceptionCaught。

    另外服務器端Handler繼承的是ChannelInboundHandlerAdapter,而不是SimpleChannelInboundHandler,至于這兩者的區別,這里不贅述,大家自行百度吧。

    代碼如下:

    import io.netty.*;

    /**

     * @Date: 2020/6/1 11:47

     * @Description: 服務器端I/O處理類

     */

    @ChannelHandler.Sharable

    public class HandlerServerHello extends ChannelInboundHandlerAdapter

    {

        @Override

        public void channelRead(ChannelHandlerContext ctx, Object msg)  throws Exception

        {

            //處理收到的數據,并反饋消息到到客戶端

            ByteBuf in = (ByteBuf) msg;

            System.out.println("收到客戶端發過來的消息: "+ in.toString(CharsetUtil.UTF_8));

     

            //寫入并發送信息到遠端(客戶端)

            ctx.writeAndFlush(Unpooled.copiedBuffer("你好,我是服務端,我已經收到你發送的消息", CharsetUtil.UTF_8));

        }

     

        @Override

        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception

        {

            //出現異常的時候執行的動作(打印并關閉通道)

            cause.printStackTrace();

            ctx.close();

        }

    }

    以上代碼很簡潔,大家注意和客戶端Handler類進行比較。

    10.3.2)創建服務器端啟動類:

    服務器端啟動類比客戶端啟動類稍顯復雜一點,先貼出代碼如下:

    import io.netty.*;

    import java.net.InetSocketAddress;

     

    /**

     * @Date: 2020/6/1 11:51

     * @Description: 服務器端啟動類

     */

    public class AppServerHello

    {

        private int port;

     

        public AppServerHello(int port)

        {

            this.port = port;

        }

     

        public void run() throws Exception

        {

            EventLoopGroup group = newNioEventLoopGroup();//Netty的Reactor線程池,初始化了一個NioEventLoop數組,用來處理I/O操作,如接受新的連接和讀/寫數據

            try{

                ServerBootstrap b = newServerBootstrap();//用于啟動NIO服務

                b.group(group)

                        .channel(NioServerSocketChannel.class) //通過工廠方法設計模式實例化一個channel

                        .localAddress(newInetSocketAddress(port))//設置監聽端口

                        .childHandler(newChannelInitializer<SocketChannel>() {

                            //ChannelInitializer是一個特殊的處理類,他的目的是幫助使用者配置一個新的Channel,用于把許多自定義的處理類增加到pipline上來

                            @Override

                            public void initChannel(SocketChannel ch) throws Exception {//ChannelInitializer 是一個特殊的處理類,他的目的是幫助使用者配置一個新的 Channel。

                                ch.pipeline().addLast(new HandlerServerHello());//配置childHandler來通知一個關于消息處理的InfoServerHandler實例

                            }

                        });

     

                //綁定服務器,該實例將提供有關IO操作的結果或狀態的信息

                ChannelFuture channelFuture= b.bind().sync();

                System.out.println("在"+ channelFuture.channel().localAddress()+"上開啟監聽");

     

                //阻塞操作,closeFuture()開啟了一個channel的監聽器(這期間channel在進行各項工作),直到鏈路斷開

                channelFuture.channel().closeFuture().sync();

            } finally{

                group.shutdownGracefully().sync();//關閉EventLoopGroup并釋放所有資源,包括所有創建的線程

            }

        }

     

        public static void main(String[] args)  throws Exception

        {

            new AppServerHello(18080).run();

        }

    }

    代碼說明:

    • 1)EventLoopGroup:實際項目中,這里創建兩個EventLoopGroup的實例,一個負責接收客戶端的連接,另一個負責處理消息I/O,這里為了簡單展示流程,讓一個實例把這兩方面的活都干了;
    • 2)NioServerSocketChannel:通過工廠通過工廠方法設計模式實例化一個channel,這個在大家還沒有能夠熟練使用Netty進行項目開發的情況下,不用去深究。

    到這里,我們就把服務器端和客戶端都寫完了 ,如何運行呢,先在服務器端啟動類上右鍵,點Run 'AppServerHello.main()'菜單運行,見下圖。

    然后,再同樣的操作,運行客戶端啟動類,就能看見效果了。

    11、寫在最后

    本文的內容就到這里結束了,希望本文能夠讓大家對Netty有一個整體的認識,并大概了解其開發流程。

    Netty的功能很多,本文只是一個入門的介紹,如果大家對于Netty開發有興趣,可以關注我并給我留言,我會根據關注和留言情況,陸續再撰寫Netty實戰開發的文章。

    得到肯定和正向反饋,才有繼續寫下去的愿望和動力,畢竟寫這種事無巨細的文章,還是挺費精力的。

    附錄:更多NIO異步網絡編程資料

    Java新一代網絡編程模型AIO原理及Linux系統AIO介紹

    有關“為何選擇Netty”的11個疑問及解答

    開源NIO框架八卦——到底是先有MINA還是先有Netty?

    選Netty還是Mina:深入研究與對比(一)

    選Netty還是Mina:深入研究與對比(二)

    NIO框架入門(一):服務端基于Netty4的UDP雙向通信Demo演示

    NIO框架入門(二):服務端基于MINA2的UDP雙向通信Demo演示

    NIO框架入門(三):iOS與MINA2、Netty4的跨平臺UDP雙向通信實戰

    NIO框架入門(四):Android與MINA2、Netty4的跨平臺UDP雙向通信實戰

    Netty 4.x學習(一):ByteBuf詳解

    Netty 4.x學習(二):Channel和Pipeline詳解

    Netty 4.x學習(三):線程模型詳解

    Apache Mina框架高級篇(一):IoFilter詳解

    Apache Mina框架高級篇(二):IoHandler詳解

    MINA2 線程原理總結(含簡單測試實例)

    Apache MINA2.0 開發指南(中文版)[附件下載]

    MINA、Netty的源代碼(在線閱讀版)已整理發布

    解決MINA數據傳輸中TCP的粘包、缺包問題(有源碼)

    解決Mina中多個同類型Filter實例共存的問題

    實踐總結:Netty3.x升級Netty4.x遇到的那些坑(線程篇)

    實踐總結:Netty3.x VS Netty4.x的線程模型

    詳解Netty的安全性:原理介紹、代碼演示(上篇)

    詳解Netty的安全性:原理介紹、代碼演示(下篇)

    詳解Netty的優雅退出機制和原理

    NIO框架詳解:Netty的高性能之道

    Twitter:如何使用Netty 4來減少JVM的GC開銷(譯文)

    絕對干貨:基于Netty實現海量接入的推送服務技術要點

    Netty干貨分享:京東京麥的生產級TCP網關技術實踐總結

    新手入門:目前為止最透徹的的Netty高性能原理和框架架構解析

    寫給初學者:Java高性能NIO框架Netty的學習方法和進階策略

    少啰嗦!一分鐘帶你讀懂Java的NIO和經典IO的區別

    史上最強Java NIO入門:擔心從入門到放棄的,請讀這篇!

    手把手教你用Netty實現網絡通信程序的心跳機制、斷線重連機制

    Java的BIO和NIO很難懂?用代碼實踐給你看,再不懂我轉行!

    >> 更多同類文章 ……

    本文已同步發布于“即時通訊技術圈”公眾號:

    ▲ 本文在公眾號上的鏈接是:點此進入,原文鏈接是:http://www.52im.net/thread-3207-1-1.html



    作者:Jack Jiang (點擊作者姓名進入Github)
    出處:http://www.52im.net/space-uid-1.html
    交流:歡迎加入即時通訊開發交流群 215891622
    討論:http://www.52im.net/
    Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
    本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: 亚洲日产乱码一二三区别| 亚洲三级在线免费观看| 亚洲人成网站看在线播放| 国产精品亚洲w码日韩中文| 久久WWW色情成人免费观看| 女人体1963午夜免费视频| 日韩精品无码永久免费网站| 亚洲五月综合网色九月色| 亚洲成人午夜在线| 亚洲午夜久久久影院| 国产免费久久精品久久久| 国产一精品一AV一免费孕妇| 免费A级毛片在线播放| 中文字幕乱码系列免费| 偷自拍亚洲视频在线观看| 亚洲女女女同性video| 亚洲免费在线视频观看| 色拍自拍亚洲综合图区| 国产aⅴ无码专区亚洲av| 亚洲伊人成无码综合网| 可以免费观看的一级毛片| 日韩视频在线免费| 女人张开腿等男人桶免费视频| 永久黄色免费网站| 久久久久久毛片免费播放 | 免费看黄视频网站| 免费A级毛片在线播放| 久久精品国产大片免费观看| a毛片在线看片免费| aa级毛片毛片免费观看久| 全部在线播放免费毛片| 色一情一乱一伦一视频免费看| 亚洲成a∨人片在无码2023| 亚洲高清乱码午夜电影网| 亚洲欧美国产欧美色欲| 亚洲AV日韩AV一区二区三曲| 日韩欧美亚洲国产精品字幕久久久 | 亚洲av片劲爆在线观看| 久久久亚洲欧洲日产国码农村| 亚洲A∨无码无在线观看| 精品亚洲aⅴ在线观看|