Android與服務(wù)器的通信方式主要有兩種,一是Http通信侍筛,一是Socket通信驯镊。兩者的最大差異在于葫督,http連接使用的是“請求—響應(yīng)方式”,即在請求時建立連接通道板惑,當客戶端向服務(wù)器發(fā)送請求后橄镜,服務(wù)器端才能向客戶端返回數(shù)據(jù)。而Socket通信則是在雙方建立起連接后就可以直接進行數(shù)據(jù)的傳輸冯乘,在連接時可實現(xiàn)信息的主動推送洽胶,而不需要每次由客戶端想服務(wù)器發(fā)送請求。 那么裆馒,什么是socket姊氓?Socket又稱套接字,在程序內(nèi)部提供了與外界通信的端口喷好,即端口通信翔横。通過建立socket連接,可為通信雙方的數(shù)據(jù)傳輸傳提供通道梗搅。socket的主要特點有數(shù)據(jù)丟失率低禾唁,使用簡單且易于移植。
Socket是一種抽象層无切,應(yīng)用程序通過它來發(fā)送和接收數(shù)據(jù)荡短,使用Socket可以將應(yīng)用程序添加到網(wǎng)絡(luò)中,與處于同一網(wǎng)絡(luò)中的其他應(yīng)用程序進行通信哆键。簡單來說掘托,Socket提供了程序內(nèi)部與外界通信的端口并為通信雙方的提供了數(shù)據(jù)傳輸通道。
Socket類型為流套接字(streamsocket)和數(shù)據(jù)報套接字(datagramsocket)洼哎。流套接字將TCP作為其端對端協(xié)議烫映,提供了一個可信賴的字節(jié)流服務(wù)沼本。數(shù)據(jù)報套接字使用UDP協(xié)議噩峦,提供數(shù)據(jù)打包發(fā)送服務(wù)
基于TCP協(xié)議的Socket
1)服務(wù)器端首先聲明一個ServerSocket對象并且指定端口號,然后調(diào)用Serversocket的accept()方法接收客戶端的數(shù)據(jù)抽兆。accept()方法在沒有數(shù)據(jù)進行接收的處于堵塞狀態(tài)识补。(Socketsocket=serversocket.accept()),一旦接收到數(shù)據(jù),通過inputstream讀取接收的數(shù)據(jù)辫红。
2)客戶端創(chuàng)建一個Socket對象凭涂,指定服務(wù)器端的ip地址和端口號(Socketsocket=newSocket("172.168.10.108",8080);),通過inputstream讀取數(shù)據(jù)祝辣,獲取服務(wù)器發(fā)出的數(shù)據(jù)(OutputStreamoutputstream=socket.getOutputStream()),最后將要發(fā)送的數(shù)據(jù)寫入到outputstream即可進行TCP協(xié)議的socket數(shù)據(jù)傳輸切油。
基于UDP協(xié)議的數(shù)據(jù)傳輸
1)服務(wù)器端首先創(chuàng)建一個DatagramSocket對象蝙斜,并且指點監(jiān)聽的端口。接下來創(chuàng)建一個空的DatagramSocket對象用于接收數(shù)據(jù)(bytedata[]=newbyte[1024;]DatagramSocketpacket=newDatagramSocket(data澎胡,data.length)),使用DatagramSocket的receive方法接收客戶端發(fā)送的數(shù)據(jù)孕荠,receive()與serversocket的accepet()類似,在沒有數(shù)據(jù)進行接收的處于堵塞狀態(tài)攻谁。
2)客戶端也創(chuàng)建個DatagramSocket對象稚伍,并且指點監(jiān)聽的端口。接下來創(chuàng)建一個InetAddress對象戚宦,這個對象類似與一個網(wǎng)絡(luò)的發(fā)送地址(InetAddressserveraddress=InetAddress.getByName("172.168.1.120")).定義要發(fā)送的一個字符串个曙,創(chuàng)建一個DatagramPacket對象,并制定要講這個數(shù)據(jù)報包發(fā)送到網(wǎng)絡(luò)的那個地址以及端口號受楼,最后使用DatagramSocket的對象的send()發(fā)送數(shù)據(jù)垦搬。
WebSocket:
我們知道,在網(wǎng)絡(luò)中的兩個應(yīng)用程序(進程)需要全雙工相互通信(全雙工即雙方可同時向?qū)Ψ桨l(fā)送消息)那槽,需要用到的就是socket悼沿,它能夠提供端對端通信,對于程序員來講骚灸,他只需要在某個應(yīng)用程序的一端(暫且稱之為客戶端)創(chuàng)建一個socket實例并且提供它所要連接一端(暫且稱之為服務(wù)端)的IP地址和端口糟趾,而另外一端(服務(wù)端)創(chuàng)建另一個socket并綁定本地端口進行監(jiān)聽,然后客戶端進行連接服務(wù)端甚牲,服務(wù)端接受連接之后雙方建立了一個端對端的TCP連接义郑,在該連接上就可以雙向通訊了,而且一旦建立這個連接之后丈钙,通信雙方就沒有客戶端服務(wù)端之分了非驮,提供的就是端對端通信了。我們可以采取這種方式構(gòu)建一個桌面版的im程序雏赦,讓不同主機上的用戶發(fā)送消息劫笙。從本質(zhì)上來說,socket并不是一個新的協(xié)議星岗,它只是為了便于程序員進行網(wǎng)絡(luò)編程而對tcp/ip協(xié)議族通信機制的一種封裝填大。
websocket是html5規(guī)范中的一個部分,它借鑒了socket這種思想俏橘,為web應(yīng)用程序客戶端和服務(wù)端之間(注意是客戶端服務(wù)端)提供了一種全雙工通信機制允华。同時,它又是一種新的應(yīng)用層協(xié)議,websocket協(xié)議是為了提供web應(yīng)用程序和服務(wù)端全雙工通信而專門制定的一種應(yīng)用層協(xié)議靴寂,通常它表示為:ws://echo.websocket.org/?encoding=text HTTP/1.1磷蜀,可以看到除了前面的協(xié)議名和http不同之外,它的表示地址就是傳統(tǒng)的url地址百炬。
既然是基于瀏覽器端的web技術(shù)褐隆,那么它的通信肯定少不了http,websocket本身雖然也是一種新的應(yīng)用層協(xié)議,但是它也不能夠脫離http而單獨存在剖踊。具體來講妓灌,我們在客戶端構(gòu)建一個websocket實例,并且為它綁定一個需要連接到的服務(wù)器地址蜜宪,當客戶端連接服務(wù)端的時候虫埂,會向服務(wù)端發(fā)送一個類似下面的http報文,注意該報文中有一個upgrade首部圃验,它的作用是告訴服務(wù)端需要將通信協(xié)議切換到websocket,如果服務(wù)端支持websocket協(xié)議掉伏,那么它就會將自己的通信協(xié)議切換到websocket,同時發(fā)給客戶端類似于以下的一個響應(yīng)報文頭,返回的狀態(tài)碼為101澳窑,表示同意客戶端協(xié)議轉(zhuǎn)換請求斧散,并將它轉(zhuǎn)換為websocket協(xié)議。以上過程都是利用http通信完成的摊聋,稱之為websocket協(xié)議握手(websocket Protocol handshake)鸡捐,進過這握手之后,客戶端和服務(wù)端就建立了websocket連接麻裁,以后的通信走的都是websocket協(xié)議了箍镜。所以總結(jié)為websocket握手需要借助于http協(xié)議,建立連接后通信過程使用websocket協(xié)議煎源。同時需要了解的是色迂,該websocket連接還是基于我們剛才發(fā)起http連接的那個TCP連接。一旦建立連接之后手销,我們就可以進行數(shù)據(jù)傳輸了歇僧,websocket提供兩種數(shù)據(jù)傳輸:文本數(shù)據(jù)和二進制數(shù)據(jù)。
基于以上分析锋拖,我們可以看到诈悍,websocket能夠提供低延遲,高性能的客戶端與服務(wù)端的雙向數(shù)據(jù)通信兽埃。它顛覆了之前web開發(fā)的請求處理響應(yīng)模式侥钳,并且提供了一種真正意義上的客戶端請求,服務(wù)器推送數(shù)據(jù)的模式讲仰,特別適合實時數(shù)據(jù)交互應(yīng)用開發(fā)慕趴。
WebSocket 是 HTML5 一種新的協(xié)議。它實現(xiàn)了瀏覽器與服務(wù)器全雙工通信鄙陡,能更好的節(jié)省服務(wù)器資源和帶寬并達到實時通訊冕房,它建立在 TCP 之上,同 HTTP 一樣通過 TCP 來傳輸數(shù)據(jù)趁矾,但是它和 HTTP 最大不同是:
WebSocket 是一種雙向通信協(xié)議耙册,在建立連接后,WebSocket 服務(wù)器和 Browser/Client Agent 都能主動的向?qū)Ψ桨l(fā)送或接收數(shù)據(jù)毫捣,就像 Socket 一樣详拙;
WebSocket 需要類似 TCP 的客戶端和服務(wù)器端通過握手連接,連接成功后才能相互通信蔓同。
相對于傳統(tǒng) HTTP 每次請求-應(yīng)答都需要客戶端與服務(wù)端建立連接的模式饶辙,WebSocket 是類似 Socket 的 TCP 長連接的通訊模式,一旦 WebSocket 連接建立后斑粱,后續(xù)數(shù)據(jù)都以幀序列的形式傳輸弃揽。在客戶端斷開 WebSocket 連接或 Server 端斷掉連接前,不需要客戶端和服務(wù)端重新發(fā)起連接請求则北。在海量并發(fā)及客戶端與服務(wù)器交互負載流量大的情況下矿微,極大的節(jié)省了網(wǎng)絡(luò)帶寬資源的消耗,有明顯的性能優(yōu)勢尚揣,且客戶端發(fā)送和接受消息是在同一個持久連接上發(fā)起涌矢,實時性優(yōu)勢明顯。
在客戶端快骗,new WebSocket 實例化一個新的 WebSocket 客戶端對象娜庇,連接類似 ws://yourdomain:port/path 的服務(wù)端 WebSocket URL,WebSocket 客戶端對象會自動解析并識別為 WebSocket 請求方篮,從而連接服務(wù)端端口思灌,執(zhí)行雙方握手過程,可以看到恭取,客戶端發(fā)起的 WebSocket 連接報文類似傳統(tǒng) HTTP 報文泰偿,”Upgrade:websocket”參數(shù)值表明這是 WebSocket 類型請求,“Sec-WebSocket-Key”是 WebSocket 客戶端發(fā)送的一個 base64 編碼的密文蜈垮,要求服務(wù)端必須返回一個對應(yīng)加密的“Sec-WebSocket-Accept”應(yīng)答耗跛,否則客戶端會拋出“Error during WebSocket handshake”錯誤,并關(guān)閉連接攒发。
作者: DocMike
鏈接:https://www.imooc.com/article/19117
來源:慕課網(wǎng)