程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .Net WebSocket 和Socket原理的探索

.Net WebSocket 和Socket原理的探索

編輯:關於.NET
對.Net WebSocket 和Socket的原理的思考

  今早上班路上接到了一個朋友的微信信息,問我對WebSocket 是否熟悉,一楞,印象之中沒有用過這個類....來到公司後,得空問了一下度娘,原來這是一個隨著HTML5推出的一種新協議,意義在於能實現浏覽器與服務器全雙工通信(full-duplex)。度娘對此的解釋是:

  現很多網站為了實現即時通訊,所用的技術都是輪詢(polling)。輪詢是在特定的的時間間隔(如每1秒),由浏覽器對服務器發出HTTP request,然後由服務器返回最新的數據給客戶端的浏覽器。這種傳統的HTTP request 的模式帶來很明顯的缺點 – 浏覽器需要不斷的向服務器發出請求,然而HTTP request 的header是非常長的,裡面包含的有用數據可能只是一個很小的值,這樣會占用很多的帶寬。   而比較新的技術去做輪詢的效果是Comet – 用了AJAX。但這種技術雖然可達到全雙工通信,但依然需要發出請求。 在 WebSocket API,浏覽器和服務器只需要做一個握手的動作,然後,浏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。在此WebSocket 協議中,為我們實現即時服務帶來了兩大好處:   1. Header     互相溝通的Header是很小的-大概只有 2 Bytes   2. Server Push     如上解釋,WebSocket 是一個非常不錯的東東,然而,我那個朋友正需要使用客戶端對服務端做輪詢查詢,按照常用的解決方案,通過在客戶端輪詢地向服務端發起Http請求,或者通過Socket直接建立長連接獲取最新的數據,然後更新呈現的內容便可以完成任務,不過那好學的朋友可能覺得WebSocket 新鮮吧,不斷追問WebSocket 和剛才兩個解決方案哪個更好,WebSocket 和Socket區別在哪裡?它們的底層原理是否一樣?由於自己也從未用過WebSocket ,也不知和soket的區別在哪,那麼問題來了,網上搜了一下,關於這個問題的解答真是少之又少,然後去看了下.NET Core的開源源碼,在System.Net.WebSockets的WinHttpWebSocket類和System.Net.Sockets的Socket類當中發現了一點線索,也許能解答這個問題。
internal class WinHttpWebSocket : WebSocket
{
    .....
public async Task ConnectAsync(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options)   {    .....     _operation.SessionHandle = InitializeWinHttp(options);     _operation.ConnectionHandle = Interop.WinHttp.WinHttpConnectWithCallback( _operation.SessionHandle, uri.IdnHost, (ushort)uri.Port, 0);     ThrowOnInvalidHandle(_operation.ConnectionHandle); bool secureConnection = uri.Scheme == UriScheme.Https || uri.Scheme == UriScheme.Wss; _operation.RequestHandle = Interop.WinHttp.WinHttpOpenRequestWithCallback( _operation.ConnectionHandle, "GET", uri.PathAndQuery, null, Interop.WinHttp.WINHTTP_NO_REFERER, null, secureConnection ? Interop.WinHttp.WINHTTP_FLAG_SECURE : 0); ThrowOnInvalidHandle(_operation.RequestHandle); _operation.IncrementHandlesOpenWithCallback();   .....   }  ...... }

  

namespace System.Net.Sockets
{
  public partial class Socket : IDisposable
  {
     .......

     public void Connect(EndPoint remoteEP)
    {
      ......
      
          EndPoint endPointSnapshot = remoteEP;
          Internals.SocketAddress socketAddress = CheckCacheRemote(ref endPointSnapshot, true);
          if (!Blocking)
          {
              _nonBlockingConnectRightEndPoint = endPointSnapshot;
              _nonBlockingConnectInProgress = true;
          }

          DoConnect(endPointSnapshot, socketAddress);
    }
     private void DoConnect(EndPoint endPointSnapshot, Internals.SocketAddress socketAddress)
     {
      .......

      SocketError errorCode = SocketPal.Connect(_handle, socketAddress.Buffer, socketAddress.Size);

      ......
     }

     ......
  }
}
namespace System.Net.Sockets {  internal static class SocketPal   {     .......     public static SocketError Connect(SafeCloseSocket handle, byte[] peerAddress, int peerAddressLen) { SocketError errorCode = Interop.Winsock.WSAConnect( handle.DangerousGetHandle(), peerAddress, peerAddressLen, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); return errorCode == SocketError.SocketError ? GetLastSocketError() : SocketError.Success; }     .......   } }

  

由上面代碼可見,

(1)WebSocket最終調用了WinHTTP 的api,WinHTTP的全稱是Microsoft Windows HTTP Services, 它提供給開發者一個HTTP客戶端應用程序接口(API), 通過這種API借助HTTP協議給其他的HTTP服務器發送請求.關於WinHTTP 的詳細API,請自行查詢資料,網上一大把,這裡不再累贅copy。由此可以驗證了WebSocket是基於HTTP請求的,從調用的WinHTTPAPI方法名稱可以得知,都是帶有回調的方法,也正驗證了WebSocket的雙工通信的特點。

(2)Socket最終是調用了windows的Winsock接口,Winsock是Windows下的網絡編程接口,它是由Unix下的BSD Socket發展而來,是一個與網絡協議無關的編程接口。具體信息請自行查詢網上資源。

因此,我個人覺得,WebSocket和Socket在技術上並沒有太多關系,底層原理也是不同的,WebSocket 是為了滿足基於 Web 的日益增長的實時通信需求而產生的,可以在一些實時通信時,代替采用 HTTP 協議不斷發送請求的通用的方式,以達到帶寬浪費和服務器 CPU 的消耗,更重要的是它是一種協議,而Socket是應用層與TCP/IP協議族通信的中間軟件抽象層,它是一組接口,並不是協議,WebSocket不能等同Socket,也不是Socket的演化,更不能代替Socket。

ps:以上是我的愚見,廢話比較多哈,敬請諒解,由於本身技術水平有限,無法在每個細節都深入研究,如有不妥之處,請路過的大神多加指點,小弟在此謝過 ^_^
Websocket和http協議類似,建立在tcp之上,和socket不是同一類東西。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved