對於有過網絡編程經驗的開發者來講,使用何種數據傳輸層協議來實現數據的通訊,是個很是基礎的問題,它涉及到你的第一行代碼該如何編寫。
從PC時代的IM開始,IM開發者就在爲數據傳輸協議的選型爭論不休(好比:《爲何QQ用的是UDP協議而不是TCP協議?》這樣的問題,隔一段時間就能在社區裏看到)。到了移動互聯網時代,鑑於移動網絡的不可靠性等特色,再加上手機的省電策略、流量壓縮等,爲這個問題的回答增了更多的不肯定因素。
對於有選擇困難證的人來講,基於以上因素,加上UDP和TCP協議的本質差別,這樣的選擇確實很糾結。本文將從做者的實踐總結,給出自已的觀點,若有異議還請理性回覆,不爲找噴,僅供參考。
說明:本文引用了DDPush的技術資料,感謝原做者。 (本文同步發佈於:http://www.52im.net/thread-33-1-1.html)php
- 即時通信開發交流羣: 215891622 [推薦]html
- 移動端IM開發推薦文章:《新手入門一篇就夠:從零開發移動端IM》android
《爲何QQ用的是UDP協議而不是TCP協議?》
《UDP中一個包的大小最大能多大》
《基於TCP協議的移動端IM仍然須要心跳保活機制》
《NAT詳解:基本原理、穿越技術(P2P打洞)、端口老化等》
《計算機網絡通信協議關係圖(中文珍藏版)》
《理論經典:TCP協議的3次握手與4次揮手過程詳解》
《微信對網絡影響的技術試驗及分析(論文全文)》算法
TCP仍是UDP?長鏈接如何實現?如何實現心跳機制?心跳的間隔如何肯定?這些問題都是討論移動端IM、消息推送等相似話題時,幾乎必定被問到的問題。這裏嘗試正本清源一下。編程
在分析到底應該使用UDP仍是TCP以前,有必要先討論一下互聯網與移動互聯網的網絡環境特色。
互聯網的網絡基礎建設,通過十幾年長期的發展,已經較爲穩定和成熟,PC終端、操做系統的能力也達到了較高的水平。
而移動互聯網,因爲涉及到無線電話網絡基站、2G、3G和4G技術的不斷髮展,其穩定性、帶寬、資源分配等各方面雖日趨完善,但當前終究還有很多問題的存在。另外,因爲移動互聯網其「移動」的本質,加上智能終端設備(智能手機、平板電腦)的發展較晚,目前還在不斷演變的狀況,與互聯網相比,移動互聯網仍是低速、不穩定、終端能力稍弱的狀況。並且因爲其「移動」本質,短期內很難達到互聯網的質量。
因此,在互聯網的環境裏面,網絡應用程序因爲網絡設施、操做系統的成熟,開發使用起來比較容易,資源也較爲充足。而移動互聯網仍是要「斤斤計較」。安全
智能終端設備的電池續航能力始終是技術瓶頸。在連續使用的狀況下,絕大部分智能設備電池沒法支持兩個小時以上。因此在沒有外部電源的狀況,智能終端設備必須頻繁、長時間休眠,這將極大地影響兩種網絡環境下的網絡應用場景。服務器
這個話題每每被不少人忽略,但它有着相當重要的影響。雖然大部分人都很清楚IP地址的緊缺致使的動態IP分配的必然,卻忽略了因爲IP地址不足引發的端口資源不足。
因爲須要動態分配IP地址(這裏不只僅指互聯網入口的IP,還包括局域網內部的IP),路由器的工做原理都是通過端口映射,把內部網絡(包括PC、手機、平板、Wifi、2G、3G、4G)IP與端口映射成外部IP(一般是公網IP)和對應的端口,並維持這個映射關係,才能正常地修改、轉發報文信息,保證內部各個ip、端口與外部的各個ip、端口的通訊。
然而,單個IP地址的端口資源是有限的,理論上限是65535個端口。對於普通寬帶路由器來講,這個已經很充足了。可是!對於大型的網絡服務、網絡主幹接入點等來講,若是IP資源不足,每一個IP幾萬個端口的資源很快會耗盡,從而影響正常通信。(有關NAT技術原理,請參見《NAT詳解:基本原理、穿越技術(P2P打洞)、端口老化等》)微信
正由於如此,全部的路由器都會爲每一個端口映射關係設置老化時間,若是老化時間倒數到0,則端口映射關係失效,該端口被釋放給其餘鏈接使用。若是端口所有耗盡,則沒法再新建內部與外部的網絡鏈接。
端口映射老化時間,比不少人想象中的要短不少。通常的家用寬帶路由器,老化時間通常是兩三分鐘;在有線寬帶運營商接入部分,老化時間可能少於兩分鐘。在無線電話網絡運營商接入部分(例如GPRS鏈接),老化時間甚至不超過一分鐘!
也就是說,任何一個網絡通信(無論是TCP或UDP),若是幾分鐘以內沒有網絡報文傳輸,其佔用的IP地址端口將被路由器回收。這個時候該次通訊必將終止,無論TCP仍是UDP,神馬都是浮雲。
更殘酷的事實是,互聯網可認爲是由無數個路由器鏈接而成的,一個網絡通訊每每須要經過n個路由器,每一個路由器都會爲一次通訊創建本身的端口映射。只要其中一個路由器回收其端口,則整個通信中斷。
這也是不少人疑惑爲何TCP的KeepAlive參數沒法保證長鏈接的緣由。TCP的KeepAlive默認是兩個小時(並且該參數仍是TCP的可選實現,不是必然實現),在路由器端口映射老化時間的影響下,必然沒法發揮其做用。實際上,該參數在單一的局域網內纔可能被使用上,還要依賴具體的操做系統。
因爲路由器端口映射的存在,加上智能終端頻繁、長時間的休眠,TCP長鏈接的實用性在移動互聯網狀況下極大地打了折扣。
也由於如此,移動端IM、推送系統必須實現所謂的心跳包機制,以保持端口映射關係的老化時間不會減小到0而被回收,從而避免鏈接中斷。(有關TCP協議下的心跳問題,請參見:《基於TCP協議的移動端IM仍然須要心跳保活機制》)網絡
無論是UDP仍是TCP,最終都是應用服務端的設備去提供服務的。而TCP因爲提供了安全可靠的流服務,其對計算機、網絡資源的消耗是遠遠大於UDP協議的。對於配置較好的主流服務器,配備大量的內存(數十G至上百G內存),與高速的磁盤、網卡,是能同時支持數百萬個TCP鏈接的。不過這裏須要較專業的服務器設置,須要調整很多系統參數,再加上服務程序的配合。另外,TCP鏈接的創建、維持與釋放,都是須要較昂貴的計算、網絡資源的。
終端在線服務,如果一個較爲簡單的服務,未必使用上TCP衆多的高級功能,但承受TCP的昂貴成本,未必值得。若是能用UDP來提供服務,單服務器的承載能力,是能夠去到TCP服務的數十倍,甚至上百倍的增加。這也是爲何DNS這種併發數巨大的服務器提供UDP接口的緣由。
另外,上百萬TCP鏈接的網絡服務,其編程的難度、程序複雜度、調試難度、服務器運維成本、網絡成本等都遠遠高於UDP。
而UDP編程,與上百萬個終端通信的難度與成本則低不少。若是提供的網絡服務不是基於流的服務,也容許必定的失敗機率(例如P2P),則UDP每每是更適合的方式。架構
不過,移動端IM系統、推送系統一方面提供終端在線服務,另一方面也須要考慮內容信息的完整性和安全性。畢竟信息的丟失,或者通信的被竊聽,都是難以接受的。而TCP無論在網絡層的可靠性控制,仍是在應用層的安全支持(例如HTTPS),都爲應用提供沒法替代的強大功能和便利。
綜合以上所述,其實答案也呼之欲出。
如今的移動端IM、推送系統,既面對移動互聯網的不肯定性,又面對智能終端頻繁的系統休眠、網絡切換,還要考慮服務端的承載成本,對於在線服務而言UDP是比TCP更適合的方式。可是因爲數據完整性、安全性的須要,又不該徹底放棄TCP的可靠與安全。
因此,我的認爲,更恰當的方式應該是:兩種通訊協議同時使用,各有側重。UDP用於保持大量終端的在線與控制,應用與業務則經過TCP去實現。這個和FTP服務控制與數據分離,採起不一樣的鏈接,有殊途同歸之處。
事實上,這個也是即時通信巨頭QQ所採用的方式。早期的時候,QQ仍是主要使用TCP協議,然後來就轉向了採用UDP的方式來保持在線,TCP的方式來上傳和下載數據。如今,UDP是QQ的默認工做方式,表現良好。相信這個也被沿用到了微信上。
簡單的考證:登陸PC版QQ,關閉多餘的QQ窗口只留下主窗口,並將其最小化。幾分鐘事後,查看系統網絡鏈接,會發現QQ進程已不保有任何TCP鏈接,但有UDP網絡活動。這時在發送聊天信息,或者打開其餘窗口和功能,將發現QQ進程會啓用TCP鏈接。
(本文同步發佈於:http://www.52im.net/thread-33-1-1.html)
[1] 網絡編程基礎資料:
《TCP/IP詳解 - 第11章·UDP:用戶數據報協議》
《TCP/IP詳解 - 第17章·TCP:傳輸控制協議》
《理論經典:TCP協議的3次握手與4次揮手過程詳解》
《理論聯繫實際:Wireshark抓包分析TCP 3次握手、4次揮手過程》
《計算機網絡通信協議關係圖(中文珍藏版)》
《NAT詳解:基本原理、穿越技術(P2P打洞)、端口老化等》
《UDP中一個包的大小最大能多大?》
《Java新一代網絡編程模型AIO原理及Linux系統AIO介紹》
《NIO框架入門(三):iOS與MINA二、Netty4的跨平臺UDP雙向通訊實戰》
《NIO框架入門(四):Android與MINA二、Netty4的跨平臺UDP雙向通訊實戰》
>> 更多同類文章 ……
[2] 有關IM/推送的通訊格式、協議的選擇:
《爲何QQ用的是UDP協議而不是TCP協議?》
《移動端即時通信協議選擇:UDP仍是TCP?》
《如何選擇即時通信應用的數據傳輸格式》
《強列建議將Protobuf做爲你的即時通信應用數據傳輸格式》
《移動端IM開發須要面對的技術問題(含通訊協議選擇)》
《簡述移動端IM開發的那些坑:架構設計、通訊協議和客戶端》
《理論聯繫實際:一套典型的IM通訊協議設計詳解》
《58到家實時消息系統的協議設計等技術實踐分享》
>> 更多同類文章 ……
[3] 有關IM/推送的心跳保活處理:
《Android進程保活詳解:一篇文章解決你的全部疑問》
《Android端消息推送總結:實現原理、心跳保活、遇到的問題等》
《爲什麼基於TCP協議的移動端IM仍然須要心跳保活機制?》
《微信團隊原創分享:Android版微信後臺保活實戰分享(進程保活篇)》
《微信團隊原創分享:Android版微信後臺保活實戰分享(網絡保活篇)》
《移動端IM實踐:實現Android版微信的智能心跳機制》
《移動端IM實踐:WhatsApp、Line、微信的心跳策略分析》
>> 更多同類文章 ……
[4] 有關WEB端即時通信開發:
《新手入門貼:史上最全Web端即時通信技術原理詳解》
《Web端即時通信技術盤點:短輪詢、Comet、Websocket、SSE》
《SSE技術詳解:一種全新的HTML5服務器推送事件技術》
《Comet技術詳解:基於HTTP長鏈接的Web端實時通訊技術》
《WebSocket詳解(一):初步認識WebSocket技術》
《socket.io實現消息推送的一點實踐及思路》
>> 更多同類文章 ……
[5] 有關IM架構設計:
《淺談IM系統的架構設計》
《簡述移動端IM開發的那些坑:架構設計、通訊協議和客戶端》
《一套原創分佈式即時通信(IM)系統理論架構方案》
《從零到卓越:京東客服即時通信系統的技術架構演進歷程》
《蘑菇街即時通信/IM服務器開發之架構選擇》
《騰訊QQ1.4億在線用戶的技術挑戰和架構演進之路PPT》
《微信技術總監談架構:微信之道——大道至簡(演講全文)》
《如何解讀《微信技術總監談架構:微信之道——大道至簡》》
《快速裂變:見證微信強大後臺架構從0到1的演進歷程(一)》
《17年的實踐:騰訊海量產品的技術方法論》
>> 更多同類文章 ……
[6] 有關IM安全的文章:
《即時通信安全篇(一):正確地理解和使用Android端加密算法》
《即時通信安全篇(二):探討組合加密算法在IM中的應用》
《即時通信安全篇(三):經常使用加解密算法與通信安全講解》
《即時通信安全篇(四):實例分析Android中密鑰硬編碼的風險》
《傳輸層安全協議SSL/TLS的Java平臺實現簡介和Demo演示》
《理論聯繫實際:一套典型的IM通訊協議設計詳解(含安全層設計)》
《微信新一代通訊安全解決方案:基於TLS1.3的MMTLS詳解》
《來自阿里OpenIM:打造安全可靠即時通信服務的技術實踐分享》
>> 更多同類文章 ……
[7] 有關實時音視頻開發:
《即時通信音視頻開發(一):視頻編解碼之理論概述》
《即時通信音視頻開發(二):視頻編解碼之數字視頻介紹》
《即時通信音視頻開發(三):視頻編解碼之編碼基礎》
《即時通信音視頻開發(四):視頻編解碼之預測技術介紹》
《即時通信音視頻開發(五):認識主流視頻編碼技術H.264》
《即時通信音視頻開發(六):如何開始音頻編解碼技術的學習》
《即時通信音視頻開發(七):音頻基礎及編碼原理入門》
《即時通信音視頻開發(八):常見的實時語音通信編碼標準》
《即時通信音視頻開發(九):實時語音通信的迴音及迴音消除概述》
《即時通信音視頻開發(十):實時語音通信的迴音消除技術詳解》
《即時通信音視頻開發(十一):實時語音通信丟包補償技術詳解》
《即時通信音視頻開發(十二):多人實時音視頻聊天架構探討》
《即時通信音視頻開發(十三):實時視頻編碼H.264的特色與優點》
《即時通信音視頻開發(十四):實時音視頻數據傳輸協議介紹》
《即時通信音視頻開發(十五):聊聊P2P與實時音視頻的應用狀況》
《即時通信音視頻開發(十六):移動端實時音視頻開發的幾個建議》
《即時通信音視頻開發(十七):視頻編碼H.26四、V8的前世此生》
《簡述開源實時音視頻技術WebRTC的優缺點》
《良心分享:WebRTC 零基礎開發者教程(中文)》
>> 更多同類文章 ……
[8] IM開發綜合文章:
《移動端IM開發須要面對的技術問題》
《開發IM是本身設計協議用字節流好仍是字符流好?》
《請問有人知道語音留言聊天的主流實現方式嗎?》
《IM系統中如何保證消息的可靠投遞(即QoS機制)》
《談談移動端 IM 開發中登陸請求的優化》
《徹底自已開發的IM該如何設計「失敗重試」機制?》
《微信對網絡影響的技術試驗及分析(論文全文)》
《即時通信系統的原理、技術和應用(技術論文)》
《開源IM工程「蘑菇街TeamTalk」的現狀:一場虎頭蛇尾的開源秀》
>> 更多同類文章 ……
[9] 開源移動端IM技術框架資料:
《開源移動端IM技術框架MobileIMSDK:快速入門》
《開源移動端IM技術框架MobileIMSDK:常見問題解答》
《開源移動端IM技術框架MobileIMSDK:壓力測試報告》
>> 更多同類文章 ……
[10] 有關推送技術的文章:
《iOS的推送服務APNs詳解:設計思路、技術原理及缺陷等》
《Android端消息推送總結:實現原理、心跳保活、遇到的問題等》
《掃盲貼:認識MQTT通訊協議》
《一個基於MQTT通訊協議的完整Android推送Demo》
《求教android消息推送:GCM、XMPP、MQTT三種方案的優劣》
《移動端實時消息推送技術淺析》
《掃盲貼:淺談iOS和Android後臺實時消息推送的原理和區別》
《絕對乾貨:基於Netty實現海量接入的推送服務技術要點》
《移動端IM實踐:谷歌消息推送服務(GCM)研究(來自微信)》
《爲什麼微信、QQ這樣的IM工具不使用GCM服務推送消息?》
>> 更多同類文章 ……
[11] 更多即時通信技術好文分類:
http://www.52im.net/forum.php?mod=collection&op=all