今早上班路上接到了一个朋友的微信信息,问我对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:以上是我的愚见,废话比较多哈,敬请谅解,由于本身技术水平有限,无法在每个细节都深入研究,如有不妥之处,请路过的大神多加指点,小弟在此谢过 ^_^

对.Net WebSocket 和Socket的原理的思考的更多相关文章

  1. 轮询以及webSocket与socket.io原理

    概述: 首先,我们知道,起初的http协议只是为了能够进行通信而被创造出来(也就是请求-响应的过程).并没有双向通信这一说,后面随着历史业务的需求,人们使用轮询http来解决双向通信也就是使用xhr或 ...

  2. php socket简单原理及实现笔记

    1.什么是socket? socket:网络上的两个程序通过一个双向的通信连接实现数据的交换,连接的一端称为一个socket. 因此socket运行是置少有2个端组成,一个为服务端一个为客户端(客户端 ...

  3. AndroidAsync :异步Socket,http(client+server),websocket和socket.io的Android类库

    AndroidAsync是一个用于Android应用的异步Socket,http(client+server),websocket和socket.io的类库.基于NIO,没有线程.它使用java.ni ...

  4. socket编程原理

    socket编程原理 1.问题的引入 1) 普通的I/O操作过程: UNIX系统的I/O命令集,是从Maltics和早期系统中的命令演变出来的,其模式为打开一读/写一关闭(open-write-rea ...

  5. Java基础知识强化之网络编程笔记02:Socket通信原理图解

    1. Socket (1)Socket套接字  网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字 (2)Socket原理机制:  • 通信两端都有Socket.  • 网 ...

  6. Python Socket通信原理

    [Python之旅]第五篇(一):Python Socket通信原理   python Socket 通信理论 socket例子 摘要:  只要和网络服务涉及的,就离不开Socket以及Socket编 ...

  7. 第1章 网络编程基础(2)——Socket编程原理

    Socket编程原理 Socket是网络通信端点的一种抽象,它提供了一种发送和接收数据的机制. 流socket(SOCK_STREAM):双向.有序.无重复.并且无记录边界 数据报Socket(SOC ...

  8. WebSocket和Socket

    WebSocket和Socket tags:WebSocket和Socket 引言:好多朋友想知道WebSocket和Socket的联系和区别,下面应该就是你们想要的 先来一张之前收集的图,我看到这张 ...

  9. 【WebSocket No.2】WebSocket和Socket实现聊天群发

    介绍: 前面写过一篇简单的websocke实现服务端.这一篇就不在说什么基础的东西主要是来用实例说话,主要是讲一下实现单聊和群组聊天和所有群发的思路设计. 直接不懂的可以看一下上一篇简单版本再来看也行 ...

随机推荐

  1. 日志文件 的管理 logrotate 配置

    于Linux 的系统安全来说,日志文件是极其重要的工具.系统管理员可以使用logrotate 程序用来管理系统中的最新的事件, 对于Linux 的系统安全来说,日志文件是极其重要的工具.系统管理员可以 ...

  2. 如何判断一个数是否为素数(zt)

    怎么判断一个数是否为素数? 笨蛋的作法: bool IsPrime(unsigned n){    if (n<2)    { //小于2的数即不是合数也不是素数    throw 0;    ...

  3. 导入GPUImage,实时滤镜相机,GUPImage遇到的问题解决,_OBJC_METACLASS_$_GBGPUImageView in GBGPUImageView.o

    导入方法转自:http://www.cnblogs.com/S2-huai/p/3881349.html.. (原文:http://www.cnblogs.com/YouXianMing/p/3709 ...

  4. 小白日记41:kali渗透测试之Web渗透-SQL手工注入(三)-猜测列名、表名、库名、字段内容,数据库写入

    SQL手工注入 靶机:metasploitable(低)  1.当无权读取infomation_schema库[MySQL最重要的源数据库,必须有root权限]/拒绝union.order by语句 ...

  5. 防火墙导致FTP传输文件为0

    在使用 ftpClient 传输文件到FTPserver时,在别的机器上可以正常使用,但是到自己的机器有就始终是0文件,发现是Mcafee 防火墙导致的,只要让防火墙放行即可. Mcafee防火墙的放 ...

  6. B. Painting Pebbles

    B. Painting Pebbles time limit per test 1 second memory limit per test 256 megabytes input standard ...

  7. [django]自定义全局context

    1. 创建一个context processor函数 新建一个文件命名为custom_processors.py,把它放到项目app文件夹(例如我的blog文件夹),添加一个返回字典的函数,其代码如下 ...

  8. Delphi 中的MD5实现方法(转)

    在Delphi自带的Indy控件中其实是提供了MD2,MD4,MD5对象的,我们可以直接使用它们来完成MD5的签名算法.而不需要再去找其它的DLL或是Pas了. 在Uses单元中引用 IdHashMe ...

  9. SNMP监控一些常用OID的总结

    做网络监控的人对SNMP的协议肯定够很熟悉,下面罗列出一些常见的OID说明,方便大家省去查阅相关资料的麻烦. 系统参数(1.3.6.1.2.1.1) OID 描述 备注 请求方式 .1.3.6.1.2 ...

  10. C#中thrift 中THttpHandler 传输数据 慢 slow 解决办法

    1. 在用c# 写thrift的服务端,来相应http请求,在用结构体传输时,会遇到一个问题,就是(在用网络)传输数据特别慢, 这是由于在发生数据是用的TStreamTransport 导致每传一个数 ...