iOS總結-Socket的分析(一)
對於Socket,我也是自己慢慢學習,參考大神文章https://www.jianshu.com/p/2dbb360886a8
實現IM方式中,第一種方式,使用第三方IM服務,對於短平快公司,採用第三個sdk實現,如雲信,環信,融雲,LeanCloud.
第三方服務商IM底層協議基本上都是TCP.使用第三方sdk甚至不需要自己去搭建IM後臺.
缺點: 定製化程度太高,很多東西不可控.需要費用.如果IM對於APP只是一個輔助功能,那麼用第三方服務頁可以.
另一種方式,我們自己去實現
我們自己實現需要選擇:
1.首先面臨的就是傳輸協議的選擇,TCP還是UDP
2.其次是我們需要去選擇使用哪種聊天協議
基於Scoket或WebScoket或其他的私有協議
MQTT
XMPP
3.我們是自己去基於OS底層Socket進行封裝還是在第三方框架的基礎上進行封裝
4.傳輸資料的格式,我們是用Json, XML 還是谷歌推出ProtocolBuffer
5.我們還有一些細節問題需要考慮, 如TCP的長連線如何保持,心跳機制, Qos機制,重連機制等等.當然,除此之外,我們還有一些安全問題需要考慮.
傳輸協議的選擇
實現IM,首先從傳輸層協議來說,我們有兩種選擇:TCP 或 UDP
有關移動端IM/推送系統的協議選型: UDP / TCP 參考:
有關IM的資料傳輸協議的選型,是鑑於移動網際網路時代,行動網路的不可靠性等特點,加上手機的省電策略,流量壓縮等
UDP vs TCP
1. TCP還是UDP? 長連線如何實現, 如何實現心跳機制? 心跳的間隔如何確定? 這些問題都是討論移動端IM,訊息推送等類似話題時,被問到的問題.
2. 網際網路/移動網際網路網路環境
PC端,作業系統的能力都達到了較高水平.
移動網際網路,涉及到無線電話網路基站/2G/3G/4G,其穩定性,頻寬,資源分配等各方面雖日趨完善,但是還是有不少問題.還是低速/不穩定/終端能力稍弱等情況.
3. 智慧終端電池續航能力,系統休眠
電池續航能力始終是技術瓶頸.
4.IPv4資源,埠資源
IP地址的緊缺導致的動態IP分配的必然,卻忽略了由於IP地址不足引起的埠資源不足.
動態分配IP地址(這裡不僅僅指網際網路入口的IP,還包括區域網內部的IP),路由器的工作原理都是經過埠對映,把內部網路(包括PC/手機/平板/Wifi/2G/3G/4G)IP與埠對映成外部IP(通常是公網IP)和對應的埠,並維持這個對映關係,才能正常修改,轉發報文資訊,保證內部各個ip/埠與外部的各個ip/埠的通訊.
單個IP地址埠理論上是65535個埠.
5.埠對映老化問題
所有路由器都會為每個埠對映關係設定老化時間, 老化時間倒數到0 ,埠對映關係失效,埠被釋放給其他連線使用.
埠對映老化時間,比很多人想象中的要短很多.一般的家用寬頻路由器,老化時間一般是兩三分鐘; 在有線寬頻運營商接入部分,老化時間可能少於兩分鐘.在無線電話網路運營商接入部分,老化時間甚至不超過一分鐘.
也就是說,任何一個網路通訊(不管TCP/UDP),如果幾分鐘之內沒有網路報文傳輸, 其佔用的IP地址埠將被路由器回收.這個時候該次通訊必將終止,不管TCP/UDP,神馬都是浮雲.
網際網路可認為是由無數個路由器連線而成的,一個網路通訊往往需要通過n個路由器,每個路由器都會為一次通訊建立自己的埠對映.只要其中一個路由器回收其埠,則整個通訊中斷.
這也是TCP的KeepAlive引數無法保證長連線的原因.TCP的keepAlive預設是兩個小時(而且該引數還是TCP的可選實現,不是必然實現),在路由器埠對映老話時間的影響下,必然無法發揮其作用.
由於路由器埠對映的存在,加上只能終端頻繁,長時間的休眠,TCP長連線的實用性在移動網際網路情況下極大地打了折扣.
也因為如此,移動端IM/推送系統必須實現所謂的心跳包機制,以保持埠對映關係的老化時間不會減少到0而被回收,從而避免連結中斷.
6.服務端承載能力
不管是UDP還是TCP, 都是應用伺服器的裝置區提供服務的. 而TCP由於提供了安全可靠的流服務, 對計算機,網路資源的消耗是遠遠大於UDP協議的. 終端線上服務,若是一個較為簡單的服務, 未必使用上TCP眾多的高階功能,但承受TCP的昂貴成本,未必值得.如果能用UDP來提供服務,單伺服器的承載能力,是可以去到TCP伺服器的數十倍,甚至上百倍的增長.這也是為什麼DNS這種併發數巨大的伺服器提供UDP介面的原因.
上百萬TCP連線的網路服務,其程式設計的難度,程式複雜度,除錯難度,伺服器運維成本,網路成本等遠遠高於UDP.如果提供的網路服務不是基於流的服務,也允許一定的失敗機率如P2P,則UDP往往是更適合的方式.
7. 高階應用網路通訊要求
移動端IM系統/推送系統一方面提供終端線上服務, 另一方面也需要考慮內容資訊的完整性和安全性.畢竟資訊的丟失或通訊被竊聽,都是問題.TCP不管在網路層的可靠性控制,還是在應用層的安全支援(如HTTPS),都為應用提供無法替代的便利.
總結:
移動端IM/推送系統,既面對移動網際網路的不確定性,又面對智慧終端頻繁的系統休眠/網路切換,還要考慮服務端的承載成本,對於線上服務UDP比TCP更適合的方式.但是為了資料完整性/安全性的需要,又不應完全放棄TCP可靠與安全.
所以 兩種通訊協議同時使用,各有側重.UDP用於保持大量終端的線上與控制,應用與業務則通過TCP去實現.這個和FTP服務控制與資料分離,採用不同的連線類似.
早起的QQ主要使用TCP協議,後來轉向了採用UDP方式保持線上,TCP來上傳和下載資料.如: 登入PC端QQ,
一般的傳輸協議還是用TCP比較好.
接下來是聊天協議的實現
1.基於Socket原生,代表框架 CocoaAsyncSocket
2.基於WebScoket:代表框架SocketRocket
3.基於MQTT: 代表框架MQTTKit
4.基於XMPP: 代表框架XMPPFramework
或者是基於OS底層Scoket企業實現我們自定義封裝.
MQTT/XMPP為聊天協議, 它們是最上層的協議,而webScoket是傳輸通訊協議,它是基於Socket封裝的一個協議.而通常我們所說的騰訊IM的私有協議,就是基於webScoket/Scoket原生進行封裝的一個聊天協議
XMPP 優點: 協議開源,可拓展性強,在各個端(包括伺服器)有各種語言的實現,開發者接入方便
缺點:確定也是不少,XML表現力弱,有太多冗餘資訊,流量大,實際使用時有大量坑
MQTT 優點:協議簡單,流量少,訂閱+推送模式,非常適合Uber/滴滴的小車軌跡的移動
缺點:它並不是一個專門為IM設計的協議,多使用於推送.IM情景要複雜多,如加入對話,建立對話等
私有協議 優點:目前主流IM APP都是使用私有協議,一個被良好設計的私有協議優點非常明顯.高效,節約流量,一般使用二進位制協議,安全性高,難以破解.
缺點:開發初期沒有現有樣列參考,對於設計者要求高
iOS要做一個IM產品,一般都是基於Scoket/WebScoket,再加上一些私有協議來保證.
1.直接用OS底層Socket來實現一個簡單IM
實現思路:建立Socket,和伺服器的Socket對接上,然後開始傳輸資料就可以.
無論c/c++/java語言,都要講Socket,Socket就是使用TCP/IP或UDP/IP協議的一組程式設計介面.
我們在應用層,使用socket,來實現程序之間的通訊,跨網路的,如果沒有socket,我們要直面TCP/IP協議.