今天咱們來盤一盤Socket通信和WebSocket協議在即時通信的小應用——聊天。html
理論你們估計都知道得差很少了,小編也經過查閱各類資料對理論知識進行了充電,發現好多demo似懂非懂,拷貝回來又運行不了,前端
後來一咬牙,決定本身寫一個demo出來,因此咱們這裏就不作理論延伸,只作demo演示,有不懂的能夠在評論區討論討論。web
demo演示有兩個,一個C#的Windows窗體應用程序,一個是net mvc。(小編demo編譯器是visual studio2013)瀏覽器
Socket通信:安全
Socket原理:服務器
socket由IP地址和端口號組成,能夠經過TCP,UDP,IP協議實現不一樣虛擬機或不一樣計算機之間的通訊,效率較高。websocket
現階段socket通訊使用TCP、UDP協議,相對應UDP來講,TCP則是比較安全穩定的協議了。本文只涉及到TCP協議來講socket通訊。網絡
首先講述TCP/IP的三次握手,在握手基礎上延伸socket通訊的基本過程。mvc
下面介紹最臭名昭著的三次握手四次揮手:socket
1 客戶端發送syn報文到服務器端,並置發送序號爲x。
2 服務器端接收到客戶端發送的請求報文,而後向客戶端發送syn報文,而且發送確認序號x+1,並置發送序號爲y。
3 客戶端受到服務器發送確認報文後,發送確認信號y+1,並置發送序號爲z。至此客戶端和服務器端創建鏈接。
在此基礎上,socket鏈接過程爲:
服務器監聽:服務器端socket並不定位具體的客戶端socket,而是處於等待監聽狀態,實時監控網絡狀態。
客戶端請求:客戶端clientSocket發送鏈接請求,目標是服務器的serverSocket。爲此,clientSocket必須知道serverSocket的地址和端口號,進行掃描發出鏈接請求。
鏈接確認:當服務器socket監聽到或者是受到客戶端socket的鏈接請求時,服務器就響應客戶端的請求,建議一個新的socket,把服務器socket發送給客戶端,一旦客戶端確認鏈接,則鏈接創建。
注:在鏈接確認階段:服務器socket即便在和一個客戶端socket創建鏈接後,還在處於監聽狀態,仍然能夠接收到其餘客戶端的鏈接請求,這也是一對多產生的緣由。
socket鏈接原理知道了,咱們編寫最基本最簡單的socket通訊
實現的功能——聊天室
服務端:
客戶端:
因爲代碼有窗體和類,放在這裏比較多,我就不粘貼出來了,下載源碼能夠直接查看源碼。
百度網盤:https://pan.baidu.com/s/1bnY7ldN9gyUmB6q3cXaTEg
提取碼:f7he
效果圖:
源碼下載:
百度網盤:https://pan.baidu.com/s/1bnY7ldN9gyUmB6q3cXaTEg
提取碼:f7he
WebSocket協議:
webSocket原理:
WebSocket 是 HTML5 開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議。
WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,容許服務端主動向客戶端推送數據。在 WebSocket API 中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並進行雙向數據傳輸。
在 WebSocket API 中,瀏覽器和服務器只須要作一個握手的動做,而後,瀏覽器和服務器之間就造成了一條快速通道。二者之間就直接能夠數據互相傳送。
如今,不少網站爲了實現推送技術,所用的技術都是 Ajax 輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,而後由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器須要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費不少的帶寬等資源。
HTML5 定義的 WebSocket 協議,能更好的節省服務器資源和帶寬,而且可以更實時地進行通信。
瀏覽器經過 JavaScript 向服務器發出創建 WebSocket 鏈接的請求,鏈接創建之後,客戶端和服務器端就能夠經過 TCP 鏈接直接交換數據。
當你獲取 Web Socket 鏈接後,你能夠經過 send() 方法來向服務器發送數據,並經過 onmessage 事件來接收服務器返回的數據。
屬性 | 描述 |
---|---|
Socket.readyState | 只讀屬性 readyState 表示鏈接狀態,能夠是如下值:
|
Socket.bufferedAmount | 只讀屬性 bufferedAmount 已被 send() 放入正在隊列中等待傳輸,可是尚未發出的 UTF-8 文本字節數。 |
事件 | 事件處理程序 | 描述 |
---|---|---|
open | Socket.onopen | 鏈接創建時觸發 |
message | Socket.onmessage | 客戶端接收服務端數據時觸發 |
error | Socket.onerror | 通訊發生錯誤時觸發 |
close | Socket.onclose | 鏈接關閉時觸發 |
方法 | 描述 |
---|---|
Socket.send() | 使用鏈接發送數據 |
Socket.close() | 關閉鏈接 |
實現的功能——聊天室:
WebSocket 協議本質上是一個基於 TCP 的協議。
爲了創建一個 WebSocket 鏈接,客戶端瀏覽器首先要向服務器發起一個 HTTP 請求,這個請求和一般的 HTTP 請求不一樣,包含了一些附加頭信息,
其中附加頭信息"Upgrade: WebSocket"代表這是一個申請協議升級的 HTTP 請求,服務器端解析這些附加的頭信息而後產生應答信息返回給客戶端,
客戶端和服務器端的 WebSocket 鏈接就創建起來了,雙方就能夠經過這個鏈接通道自由的傳遞信息,而且這個鏈接會持續存在直到客戶端或者服務器端的某一方主動的關閉鏈接。
代碼主要分爲3部分組成:前端html頁面、服務器端ashx通常處理程序、封裝的消息發送幫助類。
代碼比較多,不方便粘貼出來,直接連接下載:
百度網盤:https://pan.baidu.com/s/1AEHfRZzBFWEpcOehNBOjRg
提取碼:pu2f
注意,這個demo在Windows7上面是沒法運行的,由於Windows7上面沒有webSocket協議,也許有其餘方法,可是我沒找到,我是在Windows10上面運行的,Windows8也能夠。
須要安裝webSocket協議,相似於iis安裝,具體看下圖:
然而Windows7是沒有這個的,看圖:
效果圖:
源碼下載:
百度網盤:https://pan.baidu.com/s/1AEHfRZzBFWEpcOehNBOjRg
提取碼:pu2f
C# Socket 的demo:
百度網盤:https://pan.baidu.com/s/1bnY7ldN9gyUmB6q3cXaTEg
提取碼:f7he
net WebSocket的demo
百度網盤:https://pan.baidu.com/s/1AEHfRZzBFWEpcOehNBOjRg
提取碼:pu2f
總結:這兩種方式都有各自的侷限性,實際項目中咱們能夠根據自身狀況進行優化,webscoket對於系統的選擇比較高。
demo有了,快去下載來試試吧,最快的成功就是複製,至於裏面的邏輯咱們能夠慢慢來。