Jack Jiang

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

          導航

          公告


            ① 即時通訊開發(fā)社區(qū)
            地址: 52im.net
            專業(yè)的資料、社區(qū)

            ② 關注我的公眾號:

            讓技術不再封閉

            ③ 我的Github
            地址: 點此進入
            好代碼,與大家分享
          <2021年4月>
          28293031123
          45678910
          11121314151617
          18192021222324
          2526272829301
          2345678

          常用鏈接

          留言簿(289)

          隨筆檔案

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          60天內閱讀排行

          文中引用了參考資料中的部分內容,本文參考資料詳見文末“參考資料”一節(jié),感謝資料分享者。

          1、引言

          對于IM開發(fā)者而言,網(wǎng)絡保活這件事再熟悉不過了,比如這是我最近一篇有關網(wǎng)絡保活話題文章《一文讀懂即時通訊應用中的網(wǎng)絡心跳包機制:作用、原理、實現(xiàn)思路等》,以及我分享的大量代碼實戰(zhàn)編碼中也都必須要考慮這個問題的實現(xiàn),比如最近的這篇《跟著源碼學IM(五):正確理解IM長連接、心跳及重連機制,并動手實現(xiàn)》。

          對于IM這種應用而言,應用層的網(wǎng)絡保活的最直接辦法就是心跳機制,比如主流的IM里有微信、QQ、釘釘、易信等等,可能代碼實現(xiàn)細節(jié)有所差異,但理論上無一例外都是這樣實現(xiàn)。(PS:沒錯,當初微信跟運營商間的“信令危機”就是跟這個有關

          所謂的網(wǎng)絡心跳,通常是客戶端每隔一小段時間向服務器發(fā)送一個數(shù)據(jù)包(即心跳包),通知服務器自己仍然在線(心跳包中同時可能傳輸一些必要的數(shù)據(jù))。發(fā)送心跳包,從通信層面來說就是為了保持長連接,至于這個包的內容,是沒有什么特別規(guī)定的,但在移動端IM中為了省流量,一般都是很小的包(比如某些第3方的IM云為了說明心跳不費流量,號稱1字節(jié)的心跳包)。

          但經(jīng)常有人會問到,既然TCP協(xié)議本身有KeepAlive保活這個東西(見:《TCP/IP詳解 卷1 - 第23章·TCP的保活定時器),為什么還要自已在應用層去實現(xiàn)網(wǎng)絡保活/心跳機制呢?

          沒錯,通常面視即時通訊/IM方面的程序員時,這幾乎是必提問題!

          要解答這個問題,我通常建議看看《為什么說基于TCP的移動端IM仍然需要心跳保活?》這篇。但限于篇幅,該篇并沒有深入探討TCP協(xié)議本身的KeepAlive機制,所以這次借本文想把TCP協(xié)議的KeepAlive保活機制給詳細的整理出來,以便大家能深入其中一窺究竟。

          學習交流:

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

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

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

          (本文已同步發(fā)布于:http://www.52im.net/thread-3506-1-1.html

          2、系列文章

          本文是系列文章中的第12篇,本系列文章的大綱如下:

          3、TCP KeepAlive的初衷

          采用TCP連接的C/S模式應用中,當連接的雙方在連接空閑狀態(tài)時,如果任意一方意外崩潰、當機、網(wǎng)線斷開或路由器故障,另一方無法得知TCP連接已經(jīng)失效。

          那么,連接的另一方并不知道對端的情況,它會一直維護這個連接。而作為“服務端”來說,長時間的積累會導致非常多的半打開連接,造成端系統(tǒng)資源的消耗和浪費,且有可能導致在一個無效的數(shù)據(jù)鏈路層面發(fā)送業(yè)務數(shù)據(jù),結果就是發(fā)送失敗。

          所以各端要做到快速感知失敗,減少無效鏈接操作,這就有了TCP的KeepAlive保活探測機制。

          PS:這樣寬泛的說TCP的KeepAlive機制的必要性,貌似還不是很有說服力,下節(jié)將帶著具體的例子深入分析。

          4、從NAT角度更具體地理解TCP KeepAlive的必要性

          講到TCP的KeepAlive的必要性,多數(shù)文章都是像上節(jié)這樣比較籠統(tǒng)的進行說明,但對于愛刨根問底的開發(fā)者來說,這還遠遠不夠。

          本節(jié)將以路由器的NAT機制這個角度來具體分析TCP協(xié)議的造物主們設計KeepAlive機制的必要性。

          4.1 從NAT原理講起

          狹義上,NAT分為SNAT(原地址轉換)和DNAT(目標地址轉換),關于DNAT,有興趣的同學可以自行查閱,這里只討論SNAT。

          我們都知道,路由器的最基本功能是對第三層(網(wǎng)絡層)上的IP報文進行轉發(fā)。實際上,路由器還有很關鍵的一個功能,這便是NAT。特別是對于ISP對普通用戶鏈路上的路由器,NAT功能尤為重要。

          為什么要使用NAT?

          原因很簡單:IPv4地址非常稀缺。上網(wǎng)需求龐大,這使得ISP不可能為每一個入網(wǎng)用戶都提供一個獨立的公網(wǎng)IP,因此通常情況下,ISP會把用戶接入局域網(wǎng),使得多個用戶共享同一個公網(wǎng)IP,而每一個用戶各分得一個局域網(wǎng)內網(wǎng)IP。而連接公網(wǎng)和局域網(wǎng)的這臺路由器,稱之為網(wǎng)關(gateway),NAT的過程就發(fā)生在這臺網(wǎng)關路由器上。

          PS:P2P技術詳解(一):NAT詳解——詳細原理、P2P簡介》這篇文章有助于更深入的理解NAT原理。

          4.2 三層地址轉換

          局域網(wǎng)內的主機向公網(wǎng)發(fā)出的網(wǎng)絡層IP報文,將經(jīng)由網(wǎng)關被轉發(fā)至公網(wǎng),而在該轉發(fā)過程中發(fā)生了地址轉換。網(wǎng)關將該IP報文中的 源IP地址 從”該主機的內網(wǎng)IP”修改為”網(wǎng)關的公網(wǎng)IP”。

          比如:局域網(wǎng)主機獲得的內網(wǎng)IP為192.168.1.100,網(wǎng)關的公網(wǎng)IP為210.177.63.2,局域網(wǎng)主機向公網(wǎng)目標主機發(fā)出的IP報文中,源IP字段數(shù)據(jù)為192.168.1.100,在經(jīng)過網(wǎng)關時,該字段數(shù)據(jù)將被修改為210.177.63.2。

          為什么要這么做,相信大家已經(jīng)猜到了:公網(wǎng)上的目標主機在收到這個IP報文后,需要知道這個IP報文的來源地址,并向該來源地址發(fā)送響應報文,但如果不經(jīng)過NAT,目標主機拿到的來源地址是192.168.1.100,這顯然是一個公網(wǎng)上不可訪問到的私有地址,目標主機無法將響應報文發(fā)送到正確的來源主機上。開啟了NAT之后,IP報文的來源地址被網(wǎng)關修改為210.177.63.2,這是一個公網(wǎng)地址,目標主機將向這個地址(即網(wǎng)關路由器的公網(wǎng)地址)發(fā)送響應報文。

          但是請注意:如果這個IP報文的數(shù)據(jù)段不含傳輸層協(xié)議報文,而是一個pure的網(wǎng)絡層packet,來自目標主機的響應報文是不能被網(wǎng)關準確轉發(fā)到多臺局域網(wǎng)主機中的其中一臺的。

          PS:ICMP報文除外,其報頭中有Identifier字段用于標識不同的主機或進程,網(wǎng)關在處理Identifier時類似于下面提到的運輸層端口。

          4.3 傳輸層端口轉換表

          在三層地址轉換中,我們可以保證局域網(wǎng)內主機向公網(wǎng)發(fā)出的IP報文能順利到達目的主機,但是從目的主機返回的IP報文卻不能準確送至指定局域網(wǎng)主機(我們不能讓網(wǎng)關把IP報文廣播至全部局域網(wǎng)主機,因為這樣必然會帶來安全和性能問題)。

          為了解決這個問題,網(wǎng)關路由器需要借助傳輸層端口,通常情況下是TCP或UDP端口,由此來生成一張端口轉換表。

          讓我們通過一個實例來說明端口轉換表如何運作:

          假設局域網(wǎng)主機A192.168.1.100需要與公網(wǎng)上的目標主機B210.199.38.2:80進行一次TCP通信。其中A所在局域網(wǎng)的網(wǎng)關C的公網(wǎng)IP地址為210.177.63.2。

          步驟如下:

          1)局域網(wǎng)主機A192.168.1.100發(fā)出TCP連接請求,A上的TCP端口為系統(tǒng)分配的53600。該TCP握手包中,包含源地址和端口192.168.1.100:53600,目的地址和端口210.199.38.2:80。

          2)網(wǎng)關C將該包的原地址和端口修改為210.177.63.2:63000,其中63000是網(wǎng)關分配的臨時端口。

          3)網(wǎng)關C在端口轉換表中增加一條記錄:

          4)網(wǎng)關C將修改后的TCP包發(fā)送至目的主機B。

          5)目的主機B收到后,發(fā)送響應TCP包。該響應TCP包含有以下信息:源地址和端口210.199.38.2:80,目的地址和端口210.177.63.2:63000。

          6)網(wǎng)關C收到這個來自B的響應包后,隨即在端口轉換表中查找記錄。該記錄須符合以下條件:目的主機IP==210.199.38.2,目的主機端口==80,網(wǎng)關端口==63000。

          7)網(wǎng)關C搜索到這條記錄,記錄顯示內網(wǎng)主機IP為192.168.1.100,內網(wǎng)主機端口為53600。

          8)網(wǎng)關C將該包的目的地址和端口修改為192.168.1.100:53600。

          9)網(wǎng)關C隨即將該修改后的TCP包轉發(fā)至192.168.1.100:53600,即局域網(wǎng)主機A。此時運輸層數(shù)據(jù)的一次交換已完成。

          4.4 問題來了

          在網(wǎng)關C上,由于端口數(shù)量有限(0~65535),端口轉換表的維護占用系統(tǒng)資源,因此不能無休止地向端口轉換表中增加記錄。對于過期的記錄,網(wǎng)關需要將其刪除。

          如何判斷哪些是過期記錄?

          網(wǎng)關認為:一段時間內無活動的連接是過期的,應定時檢測轉換表中的非活動連接,并將之丟棄。而這個丟棄的過程,網(wǎng)關不會以任何的方式通告該連接的任何一端。

          通過下圖可以更直觀的理解這個過程: 

          ▲ 上圖引用自《TCP保活(TCP keepalive)

          那么問題就來了:如果一個客戶端應用程序由于業(yè)務需要,需要與服務端維持長連接(例如基于TCP的IM聊天應用),而如果在特別長的時間內這個連接沒有任何的數(shù)據(jù)交換,網(wǎng)關會認為這個連接過期并將這個連接從端口轉換表中丟棄。該連接被丟棄時,客戶端和服務端對此是完全無感知的。在連接被丟棄后,客戶端將收不到服務端的數(shù)據(jù)推送,客戶端發(fā)送的數(shù)據(jù)包也不能到達服務端。

          一個具體的例子來感受一下這個問題的嚴重性:

          某財務應用,在客戶端需要填寫大量的表單數(shù)據(jù),在客戶端與服務器端建立TCP連接后,客戶端終端使用者將花費幾分鐘甚至幾十分鐘填寫表單相關信息,終端使用者終于填好表單所需信息后,點擊“提交”按鈕。

          結果,這個時候由于中間設備早已經(jīng)將這個TCP連接從連接表中刪除了,其將直接丟棄這個報文或者給客戶端發(fā)送RST報文,應用故障產(chǎn)生,這將導致客戶端終端使用者所有的工作將需要重新來過,給使用者帶來極大的不便和損失。

          4.5 解決方法

          針對上述問題,TCP協(xié)議這一層的解決方法就是利用KeepAlive機制維持長連接,讓網(wǎng)關認為我們的TCP連接是活動的,從而避免網(wǎng)關“干掉”我們的長連接。

          通過NAT這個具體的例子,相信你已經(jīng)能更具體地理解TCP協(xié)議中KeepAlive保活機制的必要性了。

          5、TCP Keepalive工作原理

          5.1 技術原理

          當一個 TCP 連接建立之后,啟用 TCP Keepalive 的一端便會啟動一個計時器,當這個計時器數(shù)值到達 0 之后(也就是經(jīng)過tcp_keep-alive_time時間后,這個參數(shù)之后會講到),一個 TCP 探測包便會被發(fā)出。這個 TCP 探測包是一個純 ACK 包(RFC1122#TCP Keep-Alives規(guī)范建議:不應該包含任何數(shù)據(jù),但也可以包含1個無意義的字節(jié),比如0x0),其 Seq號 與上一個包是重復的,所以其實探測保活報文不在窗口控制范圍內。

          如果一個給定的連接在兩小時內(默認時長)沒有任何的動作,則服務器就向客戶發(fā)一個探測報文段,客戶主機必須處于下表中的4個狀態(tài)之一。 

          詳細解釋一下就是:

          1)客戶主機依然正常運行,并從服務器可達。客戶的TCP響應正常,而服務器也知道對方是正常的,服務器在兩小時后將保活定時器復位。

          2)客戶主機已經(jīng)崩潰,并且關閉或者正在重新啟動。在任何一種情況下,客戶的TCP都沒有響應。服務端將不能收到對探測的響應,并在75秒后超時。服務器總共發(fā)送10個這樣的探測 ,每個間隔75秒。如果服務器沒有收到一個響應,它就認為客戶主機已經(jīng)關閉并終止連接。

          3)客戶主機崩潰并已經(jīng)重新啟動。服務器將收到一個對其保活探測的響應,這個響應是一個復位,使得服務器終止這個連接。

          4)客戶機正常運行,但是服務器不可達,這種情況與2類似,TCP能發(fā)現(xiàn)的就是沒有收到探測的響應。

          直觀來說,TCP KeepAlive的交互過程大致如下圖所示: 

          ▲ 上圖引用自《TCP保活(TCP keepalive)

          5.2 具體使用舉例

          以linux內核為例,應用程序若想使用TCP Keepalive,需要設置SO_KEEPALIVE套接字選項才能生效。

          對應的,有三個重要的參數(shù):

          • 1)tcp_keepalive_time,在TCP保活打開的情況下,最后一次數(shù)據(jù)交換到TCP發(fā)送第一個保活探測包的間隔,即允許的持續(xù)空閑時長,或者說每次正常發(fā)送心跳的周期,默認值為7200s(2h);
          • 2)tcp_keepalive_probes 在tcp_keepalive_time之后,沒有接收到對方確認,繼續(xù)發(fā)送保活探測包次數(shù),默認值為9(次);
          • 3)tcp_keepalive_intvl,在tcp_keepalive_time之后,沒有接收到對方確認,繼續(xù)發(fā)送保活探測包的發(fā)送頻率,默認值為75s。

          上面談的是linux內核參數(shù)的配置,實際上其他編程語言有相應的設置方法。

          例如,Java的Netty服務器框架中也提供了相關接口:

          ServerBootstrap b = new ServerBootstrap();

                      b.group(bossGroup, workerGroup)

                       .channel(NioServerSocketChannel.class)

                       .option(ChannelOption.SO_BACKLOG, 100)

                       // 心跳監(jiān)測

                       .childOption(ChannelOption.SO_KEEPALIVE, true)

                       .handler(new LoggingHandler(LogLevel.INFO))

                       .childHandler(new ChannelInitializer<SocketChannel>() {

                           @Override

                           public void initChannel(SocketChannel ch) throwsException {

                               ch.pipeline().addLast(

                                       new EchoServerHandler());

                           }

                       });

                      // Start the server.

                      ChannelFuture f = b.bind(port).sync();

                      // Wait until the server socket is closed.

                      f.channel().closeFuture().sync();

          PS:Java程序只能做到設置SO_KEEPALIVE選項,至于TCP_KEEPCNT,TCP_KEEPIDLE,TCP_KEEPINTVL等參數(shù)配置,應用層面是沒法設置的。

          6、TCP KeepAlive可能導致的問題

          Keepalive 技術只是TCP協(xié)議中的一個可選項。因為不當?shù)呐渲每赡軙鹨恍﹩栴},所以默認是關閉的。

          具體來說,可能導致下列問題:

          • 1)在短暫的故障期間,Keepalive設置不合理時可能會因為短暫的網(wǎng)絡波動而斷開健康的TCP連接;
          • 2)需要消耗額外的寬帶和流量(對于現(xiàn)在這個時代來說,這貌似已經(jīng)不是問題了);
          • 3)在以流量計費的互聯(lián)網(wǎng)環(huán)境中增加了費用開銷。

          7、TCP KeepAlive在移動網(wǎng)絡時代的局限性

          不可否認,TCP協(xié)議作為TCP/IP協(xié)議族中最重要部分,對互聯(lián)的發(fā)展確實功不可沒(見:《技術往事:改變世界的TCP/IP協(xié)議(珍貴多圖、手機慎點))。

          但如今移動網(wǎng)絡時代,無線通信越來越普及,作為上個世紀中期發(fā)明的TCP協(xié)議來說,客觀的講,在某些場景下確實有先天不足(見:《5G時代已經(jīng)到來,TCP/IP老矣,尚能飯否?)。

          那么,又回到了本文開頭的問題——“既然TCP協(xié)議本身有KeepAlive,為什么還要自已在應用層實現(xiàn)網(wǎng)絡保活/心跳機制?”。

          以移動端IM應用為例:

          • 1)一方面,運營商ISP的網(wǎng)絡資源更為稀缺,TCP協(xié)議默認2小時的KeepAlive基本不可能實現(xiàn)IM長連接“保活”(為了提升無線網(wǎng)絡資源的利用率,運營商長則幾分鐘,短則數(shù)十秒就有可能回收空閑的網(wǎng)絡連接)。
          • 2)另一面,無線網(wǎng)絡本身存在弱網(wǎng)問題,即使TCP連接是“好的”,但實際上處于“假死”狀態(tài),也無法起到長連接該有的作用。

          所以說,IM應用層自已做網(wǎng)絡保活(心跳機制)是不可避免的。

          有關這方面的更多資料,有興趣,可以深入閱讀下面這幾篇:

          為何基于TCP協(xié)議的移動端IM仍然需要心跳保活機制?

          移動端IM開發(fā)者必讀(一):通俗易懂,理解移動網(wǎng)絡的“弱”和“慢”

          移動端IM開發(fā)者必讀(二):史上最全移動弱網(wǎng)絡優(yōu)化方法總結

          IM開發(fā)者的零基礎通信技術入門(十三):為什么手機信號差?一文即懂!

          IM開發(fā)者的零基礎通信技術入門(十四):高鐵上無線上網(wǎng)有多難?一文即懂!

          8、知識拓展:TCP Keepalive和HTTP Keep-Alive有什么區(qū)別?

          很多人會把TCP Keepalive 和 HTTP Keep-Alive 這兩個概念搞混淆。

          這里簡單介紹下HTTP Keep-Alive 。

          在HTTP/1.0中,默認使用的是短連接。也就是說,瀏覽器和服務器每進行一次HTTP操作,就建立一次連接,但任務結束就中斷連接。如果客戶端瀏覽器訪問的某個HTML或其他類型的 Web頁中包含有其他的Web資源,如JavaScript文件、圖像文件、CSS文件等;當瀏覽器每遇到這樣一個Web資源,就會建立一個HTTP會話。

          但從 HTTP/1.1起,默認使用長連接,用以保持連接特性。使用長連接的HTTP協(xié)議,會在響應頭加上Connection、Keep-Alive字段。

          如下圖所示:

          HTTP 1.0 和 1.1 在 TCP連接使用方面的差異如下圖所示: 

          通俗地總結一下:

          • 1)HTTP的Keep-Alive是為了讓TCP連接活得更久一點,在發(fā)起多個http請求時能復用同一個連接,提高通信效率;
          • 2)TCP的KeepAlive機制意圖在于探測連接的對端是否存活,是一種檢測TCP連接狀況的保鮮機制。

          9、參考資料

          [1] TCP保活(TCP keepalive)

          [2] TCP協(xié)議的KeepAlive機制與HeartBeat心跳包

          [3] HTTP keep-alive和TCP keepalive的區(qū)別,你了解嗎?

          [4] TCP KeepAlive 與 HTTP Keep-Alive 區(qū)別

          [5] tcp連接探測Keepalive和心跳包

          [6] TCP keepalive的探究 (1) : NAT和保活機制

          [7] 理解TCP長連接(Keepalive)

          [8] 為何基于TCP協(xié)議的移動端IM仍然需要心跳保活機制?

          [9] 移動端IM開發(fā)者必讀(二):史上最全移動弱網(wǎng)絡優(yōu)化方法總結

          [10] IM開發(fā)者的零基礎通信技術入門(十三):為什么手機信號差?一文即懂!

          附錄:更多網(wǎng)絡編程精華文章

          [1] 網(wǎng)絡編程(基礎)資料:

          網(wǎng)絡編程懶人入門(一):快速理解網(wǎng)絡通信協(xié)議(上篇)

          網(wǎng)絡編程懶人入門(二):快速理解網(wǎng)絡通信協(xié)議(下篇)

          網(wǎng)絡編程懶人入門(三):快速理解TCP協(xié)議一篇就夠

          網(wǎng)絡編程懶人入門(四):快速理解TCP和UDP的差異

          網(wǎng)絡編程懶人入門(五):快速理解為什么說UDP有時比TCP更有優(yōu)勢

          網(wǎng)絡編程懶人入門(六):史上最通俗的集線器、交換機、路由器功能原理入門

          網(wǎng)絡編程懶人入門(七):深入淺出,全面理解HTTP協(xié)議

          網(wǎng)絡編程懶人入門(八):手把手教你寫基于TCP的Socket長連接

          網(wǎng)絡編程懶人入門(九):通俗講解,有了IP地址,為何還要用MAC地址?

          網(wǎng)絡編程懶人入門(十):一泡尿的時間,快速讀懂QUIC協(xié)議

          網(wǎng)絡編程懶人入門(十一):一文讀懂什么是IPv6

          網(wǎng)絡編程懶人入門(十二):快速讀懂Http/3協(xié)議,一篇就夠!

          腦殘式網(wǎng)絡編程入門(一):跟著動畫來學TCP三次握手和四次揮手

          腦殘式網(wǎng)絡編程入門(二):我們在讀寫Socket時,究竟在讀寫什么?

          腦殘式網(wǎng)絡編程入門(三):HTTP協(xié)議必知必會的一些知識

          腦殘式網(wǎng)絡編程入門(四):快速理解HTTP/2的服務器推送(Server Push)

          腦殘式網(wǎng)絡編程入門(五):每天都在用的Ping命令,它到底是什么?

          腦殘式網(wǎng)絡編程入門(六):什么是公網(wǎng)IP和內網(wǎng)IP?NAT轉換又是什么鬼?

          腦殘式網(wǎng)絡編程入門(七):面視必備,史上最通俗計算機網(wǎng)絡分層詳解

          腦殘式網(wǎng)絡編程入門(八):你真的了解127.0.0.1和0.0.0.0的區(qū)別?

          腦殘式網(wǎng)絡編程入門(九):面試必考,史上最通俗大小端字節(jié)序詳解

          網(wǎng)絡編程入門從未如此簡單(一):假如你來設計網(wǎng)絡,會怎么做?

          網(wǎng)絡編程入門從未如此簡單(二):假如你來設計TCP協(xié)議,會怎么做?

          >> 更多同類文章 ……

          [2] 網(wǎng)絡編程(高階)資料:

          高性能網(wǎng)絡編程(一):單臺服務器并發(fā)TCP連接數(shù)到底可以有多少

          高性能網(wǎng)絡編程(二):上一個10年,著名的C10K并發(fā)連接問題

          高性能網(wǎng)絡編程(三):下一個10年,是時候考慮C10M并發(fā)問題了

          高性能網(wǎng)絡編程(四):從C10K到C10M高性能網(wǎng)絡應用的理論探索

          高性能網(wǎng)絡編程(五):一文讀懂高性能網(wǎng)絡編程中的I/O模型

          高性能網(wǎng)絡編程(六):一文讀懂高性能網(wǎng)絡編程中的線程模型

          高性能網(wǎng)絡編程(七):到底什么是高并發(fā)?一文即懂!

          不為人知的網(wǎng)絡編程(一):淺析TCP協(xié)議中的疑難雜癥(上篇)

          不為人知的網(wǎng)絡編程(二):淺析TCP協(xié)議中的疑難雜癥(下篇)

          不為人知的網(wǎng)絡編程(三):關閉TCP連接時為什么會TIME_WAIT、CLOSE_WAIT

          不為人知的網(wǎng)絡編程(四):深入研究分析TCP的異常關閉

          不為人知的網(wǎng)絡編程(五):UDP的連接性和負載均衡

          不為人知的網(wǎng)絡編程(六):深入地理解UDP協(xié)議并用好它

          不為人知的網(wǎng)絡編程(七):如何讓不可靠的UDP變的可靠?

          不為人知的網(wǎng)絡編程(八):從數(shù)據(jù)傳輸層深度解密HTTP

          不為人知的網(wǎng)絡編程(九):理論聯(lián)系實際,全方位深入理解DNS

          不為人知的網(wǎng)絡編程(十):深入操作系統(tǒng),從內核理解網(wǎng)絡包的接收過程(Linux篇)

          不為人知的網(wǎng)絡編程(十一):從底層入手,深度分析TCP連接耗時的秘密

          不為人知的網(wǎng)絡編程(十二):徹底搞懂TCP協(xié)議層的KeepAlive保活機制

          IM開發(fā)者的零基礎通信技術入門(十一):為什么WiFi信號差?一文即懂!

          IM開發(fā)者的零基礎通信技術入門(十二):上網(wǎng)卡頓?網(wǎng)絡掉線?一文即懂!

          IM開發(fā)者的零基礎通信技術入門(十三):為什么手機信號差?一文即懂!

          IM開發(fā)者的零基礎通信技術入門(十四):高鐵上無線上網(wǎng)有多難?一文即懂!

          IM開發(fā)者的零基礎通信技術入門(十五):理解定位技術,一篇就夠

          >> 更多同類文章 ……

          本文已同步發(fā)布于“即時通訊技術圈”公眾號。

          ▲ 本文在公眾號上的鏈接是:點此進入。同步發(fā)布鏈接是:http://www.52im.net/thread-3506-1-1.html



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


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


          網(wǎng)站導航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯(lián)系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 昌图县| 周宁县| 深圳市| 彭山县| 扎囊县| 衡山县| 长春市| 东港市| 新丰县| 东方市| 澎湖县| 滦平县| 徐汇区| 通城县| 大渡口区| 新晃| 天气| 成安县| 临洮县| 剑川县| 惠安县| 天峨县| 云阳县| 宁海县| 黄大仙区| 南岸区| 济宁市| 九江县| 高邑县| 彭阳县| 虞城县| 湘西| 舟山市| 罗定市| 岳普湖县| 赣榆县| 新乡县| 昌都县| 普格县| 建始县| 海城市|