默认
打赏 发表评论 17
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
WebSocket详解(六):刨根问底WebSocket与Socket的关系
阅读(114091) | 评论(17 收藏5 淘帖1
微信扫一扫关注!

1、前言


对于很多初次接触Web端即时通讯技术的人来说,WebSocket是个很新的概念,但无疑它也是当前Web端即时通讯技术中最热门的关键词。随便点开一篇文章,只要说打算开发Web端即时通讯类应用,老司机们无一例外推荐的都是WebSocket。

那么好了,我知道应该用WebSocket,但本着知其然知其所以然的码农习惯,我还是需要了解下面这些问题:

  • Socket 和 WebSocket 有哪些区别和联系?
  • WebSocket 和 HTML5 是什么关系?
  • 必须在浏览器中才能使用 WebSocket 吗?
  • WebSocket 能和 Socket 一样传输 raw 数据么?
  • WebSocket 和 Socket 相比会多耗费流量么?

但是,目前网上全面介绍这两种协议的中文文章并不多,或者说不够全面。我无法找到一篇文章能解决上面的所有问题。因此,我写了本文,把找到的 Socket 和 WebSocket 的相关资料做一个梳理,以方便理解。

本文并不能直接完整回答上面提出的几个问题,但读完本文,要理解上面的那些问题,是很容易的事。由于能力有限,本文不可能很长。而且,技术细节并非所有人都愿意仔细了解。但本文包含了大量的外部链接,跟随这些链接,可以找到足够多的细节,满足你/我的求知欲。Are you ready?

2、系列文章


本文是系列文章中的第5篇,本系列文章的大纲如下:


3、更多资料


Web端即时通讯新手入门贴:
新手入门贴:详解Web端即时通讯技术的原理

Web端即时通讯技术盘点请参见:
Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE

关于Ajax短轮询:
找这方面的资料没什么意义,除非忽悠客户,否则请考虑其它3种方案即可。

有关Comet技术的详细介绍请参见:
Comet技术详解:基于HTTP长连接的Web端实时通信技术
WEB端即时通讯:HTTP长连接、长轮询(long polling)详解
WEB端即时通讯:不用WebSocket也一样能搞定消息的即时性
开源Comet服务器iComet:支持百万并发的Web端即时通讯方案

更多WebSocket的详细介绍请参见:
新手快速入门:WebSocket简明教程
理论联系实际:从零理解WebSocket的通信原理、协议格式、安全性
八问WebSocket协议:为你快速解答WebSocket热门疑问
Socket.IO介绍:支持WebSocket、用于WEB端的即时通讯的框架
socket.io和websocket 之间是什么关系?有什么区别?
Web端即时通讯实践干货:如何让你的WebSocket断网重连更快速?

有关SSE的详细介绍文章请参见:
SSE技术详解:一种全新的HTML5服务器推送事件技术

更多WEB端即时通讯文章请见:
http://www.52im.net/forum.php?mod=collection&action=view&ctid=15

4、技术对比


选择了 WebSocket 技术之后,不可避免的,我要将它和其他协议以及技术做一下比较。最常见的,就是需要比较 WebSocket 与 HTTP、Socket 技术的异同。本系列文章中《WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)》、《WebSocket详解(五):刨根问底HTTP与WebSocket的关系(下篇)》两篇详细讨论了WebSocket和HTTP的关系,那么本篇将只讨论WebSocket和Socket的话题。

WebSocket 是为了满足基于 Web 的日益增长的实时通信需求而产生的。在传统的 Web 中,要实现实时通信(比如网页的QQ,聊天系统等),通用的方式是采用 HTTP 协议不断发送请求(按照以往的技术能力通常是采用轮询、Comet技术解决)。

HTTP协议是非持久化的,单向的网络协议,在建立连接后只允许浏览器向服务器发出请求后,服务器才能返回相应的数据。当需要即时通讯时,通过轮询在特定的时间间隔(如1秒),由浏览器向服务器发送Request请求,然后将最新的数据返回给浏览器。这样的方法最明显的缺点就是需要不断的发送请求,而且通常HTTP request的Header是非常长的,为了传输一个很小的数据 需要付出巨大的代价,是很不合算的,占用了很多的宽带。这种方式即浪费带宽(HTTP HEAD 是比较大的),又消耗服务器 CPU 占用(没有信息也要接受请求)。

WebSocket详解(六):刨根问底WebSocket与Socket的关系_1.gif
▲ 轮询和WebSocket技术在网络延迟上的对比(本图来自:websocket.org

而是用 WebSocket 技术,则会大幅降低上面提到的消耗,如下图所示。

WebSocket详解(六):刨根问底WebSocket与Socket的关系_2.gif
▲ 轮询和WebSocket技术在数据流量消耗上的对比(本图来自:websocket.org

关于更详细的描述,尹立的这篇文章讲得非常好:《WebSocket(2)–为什么引入WebSocket协议 》。

那么,WebSocket 到底和 Socket 又有什么联系?这就要讲到 OSI 模型和 TCP/IP 协议族。

5、OSI 模型与 TCP/IP


以下是 维基百科 中关于OSI 模型的说明:

开放式系统互联通信参考模型(英语:Open System Interconnection Reference Model,ISO/IEC 7498-1),简称为OSI模型(OSI model),一种概念模型,由国际标准化组织(ISO)提出,一个试图使各种计算机在世界范围内互连为网络的标准框架。


而 TCP/IP 协议可以看做是对 OSI 模型的一种简化(以下内容来自 维基百科):

它将软件通信过程抽象化为四个抽象层,采取协议堆叠的方式,分别实作出不同通信协议。协议套组下的各种协议,依其功能不同,被分别归属到这四个阶层之中7,常被视为是简化的七层OSI模型。


这里有一张图详细介绍了 TCP/IP 协议族中的各个协议在 OSI模型 中的分布,一图胜千言(此图高清版:点此下载):
WebSocket详解(六):刨根问底WebSocket与Socket的关系_1111.png

TCP/IP 协议和 OSI 模型的内容,在互联网上有很多。我没有必要再次介绍它们。在这里,我们只需要知道,HTTP、WebSocket 等协议都是处于 OSI 模型的最高层: 应用层 。而 IP 协议工作在网络层(第3层),TCP 协议工作在传输层(第4层)。

至于 OSI 模型的各个层次都有什么系统和它们对应,这里有篇很好的文章可以满足大家的求知欲:OSI七层模型详解

6、WebSocket 与 TCP


从上面的图中可以看出,HTTP、WebSocket 等应用层协议,都是基于 TCP 协议来传输数据的,我们可以把这些高级协议理解成对 TCP 的封装。

既然大家都使用 TCP 协议,那么大家的连接和断开,都要遵循 TCP 协议中的三次握手和四次握手 ,只是在连接之后发送的内容不同,或者是断开的时间不同。

更详细内容可阅读:wireshark抓包图解 TCP三次握手/四次挥手详解》。

对于 WebSocket 来说,它必须依赖 HTTP 协议进行一次握手 ,握手成功后,数据就直接从 TCP 通道传输,与 HTTP 无关了(具体可见文章《WebSocket详解(五):刨根问底HTTP与WebSocket的关系(下篇)》)。

7、再来八卦一下WebSocket的由来


由于年代久远,计算机方面很多事情也搞不了那么清楚。但WebSocket是一个很新的东西,可以让我们看到它是如何成为现在我们看到的这个样子的。

7.1WHATWG(Web Hypertext Application Technology Working Group)


关于HTML5的故事很多人都是知道的,w3c放弃了HTML,然后有一群人(也有说是这些人供职的公司,不过官方的文档上是说的个人)创立了WHATWG组织来推动HTML语言的继续发展,同时,他们还发展了很多关于Web的技术标准,这些标准不断地被官方所接受。WebSocket就属于WHATWG发布的Web Application的一部分(即HTML5)的产物。

7.2为什么会有WebSocket


大约在08年的时候,WG的工程师在讨论网络环境中需要一种全双工的连接形式,刚开始一直叫做「TCPConnection」,并讨论了这种协议需要支持的功能,大致已经和我们今天看到的WebSocket差不多了。他们认为基于现有的HTTP之上的一些技术(如长轮询、Comet)并满足不了这种需求,有必要定义一个全新的协议。

7.3名称的由来


在很多的关于HTML5或者WebSocket的文档中,都能看到一个名字,Hixie(Ian Hickson),他是WHATWG组织的发言人,曾供职于Netscape、Opera、Google,看工作的公司就知道这个人的背景了。

WebSocket详解(六):刨根问底WebSocket与Socket的关系_x.jpg
▲ hixie

08年6月18日,一群WHATWG的工程师在讨论一些技术问题,一个工程师提到说「我们之前讨论的那个东西,不要叫TCPConnection 了,还是起个别的名字吧 」,接着几个名字被提及,DuplexConnection,TCPSocket,SocketConnection ,一个叫mcarter(Michael Carter )的工程师说他马上要写一篇关于Comet的文章,如果可以确定这个名称,想在文章中引用这个名字。

Socket一直以来都被人用来表示网络中一个连接的两端,考虑到怎么让工程师更容易接受,后来Hixie说了一句「我看WebSocket这个名字就很适合嘛(Hixie briefly pops back online to record that "WebSocket" would probably be a good new name for the TCPConnection object)」,大家都没有异议,紧接着mcarter在Comet Daily中发表了文章《Independence Day: HTML5 WebSocket Liberates Comet From Hacks》,后来随着各大浏览器对WebSocket的支持,它变成了实际的标准,IETF也沿用了这个名字。

下边是在WHATWG文档中对WebSocket接口的定义:
enum BinaryType { "blob", "arraybuffer" };
[Constructor(USVString url, optional (DOMString or sequence<DOMString>) protocols = []), Exposed=(Window,Worker)]
interface WebSocket : EventTarget {
  readonly attribute USVString url;

  // ready state
  const unsigned short CONNECTING = 0;
  const unsigned short OPEN = 1;
  const unsigned short CLOSING = 2;
  const unsigned short CLOSED = 3;
  readonly attribute unsigned short readyState;
  readonly attribute unsigned long long bufferedAmount;

  // networking
  attribute EventHandler onopen;
  attribute EventHandler onerror;
  attribute EventHandler onclose;
  readonly attribute DOMString extensions;
  readonly attribute DOMString protocol;
  void close([Clamp] optional unsigned short code, optional USVString reason);

  // messaging
  attribute EventHandler onmessage;
  attribute BinaryType binaryType;
  void send(USVString data);
  void send(Blob data);
  void send(ArrayBuffer data);
  void send(ArrayBufferView data);
};

8、再来看看Socket


Socket可以有很多意思,和IT较相关的本意大致是指在端到端的一个连接中,这两个端叫做Socket。对于IT从业者来说,它往往指的是TCP/IP网络环境中的两个连接端,大多数的API提供者(如操作系统,JDK)往往会提供基于这种概念的接口,所以对于开发者来说也往往是在说一种编程概念。同时,操作系统中进程间通信也有Socket的概念,但这个Socket就不是基于网络传输层的协议了。

8.1Unix中的Socket


操作系统中也有使用到Socket这个概念用来进行进程间通信,它和通常说的基于TCP/IP的Socket概念十分相似,代表了在操作系统中传输数据的两方,只是它不再基于网络协议,而是操作系统本身的文件系统。

8.2网络中的Socket


通常所说的Socket API,是指操作系统中(也可能不是操作系统)提供的对于传输层(TCP/UDP)抽象的接口。现行的Socket API大致都是遵循了BSD Socket规范(包括Windows)。这里称规范其实不太准确,规范其实是POSIX,但BSD Unix中对于Socket的实现被广为使用,所以成为了实际的规范。如果你要使用HTTP来构建服务,那么就不需要关心Socket,如果你想基于TCP/IP来构建服务,那么Socket可能就是你会接触到的API。

WebSocket详解(六):刨根问底WebSocket与Socket的关系_3.png
▲ 在TCP/IP网络中HTTP的位置

从上图中可以看到,HTTP是基于传输层的TCP协议的,而Socket API也是,所以只是从使用上说,可以认为Socket和HTTP类似(但一个是成文的互联网协议,一个是一直沿用的一种编程概念),是对于传输层协议的另一种直接使用,因为按照设计,网络对用户的接口都应该在应用层。

8.3Socket名称的由来


和很多其他Internet上的事物一样,Socket这个名称来自于大名鼎鼎的ARPANET(Advanced Research Projects Agency),早期ARPANET中的Socket指的是一个源或者目的地址——大致就是今天我们所说的IP地址和端口号。最早的时候一个Socket指的是一个40位的数字(RFC33中说明了此用法,但在RFC36中并没有明确地说使用40位数字来标识一个地址),其中前32为指向的地址(socket number,大致相当于IP),后8位为发送数据的源(link,大致相当于端口号)。对他们的叫法有很多的版本,这里列举的并不严谨。

8.4端口号的野史


随着ARPANET的发展,后来(RFC433,Socket Number List)socket number被明确地定义为一个40位的数字,其中后8位被用来制定某个特定的应用使用(比如1是Telnet)。这8位数有很多名字:link、socket name、AEN(another eight number,看到这个名字我也是醉了),工程师逗逼起来也是挺拼的。

后来在Internet的规范制定中,才真正的用起了port number这个词。至于为什么端口号是16位的,我想可能有两个原因,一是对于当时的工程师来说,如果每个端口号来标识一个程序,65535个端口号也差不多够用了。二可能是为了对齐吧,_!!。

8.5Socket原本的意思


在上边提到的历史中使用到的Socket,包括TCP文档中使用到的Socket,其实指的是网络传输中的一端,是一个虚拟化的概念。

9、Socket 与 WebSocket 的关系


正如上节所述:Socket 其实并不是一个协议,它工作在 OSI 模型会话层(第5层),是为了方便大家直接使用更底层协议(一般是 TCPUDP )而存在的一个抽象层。

最早的一套 Socket API 是 Berkeley sockets ,采用 C 语言实现。它是 Socket 的事实标准,POSIX sockets 是基于它构建的,多种编程语言都遵循这套 API,在 JAVA、Python 中都能看到这套 API 的影子。

下面摘录一段更容易理解的文字(来自 http和socket之长连接和短连接区别):

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

主机 A 的应用程序要能和主机 B 的应用程序通信,必须通过 Socket 建立连接,而建立 Socket 连接必须需要底层 TCP/IP 协议来建立 TCP 连接。建立 TCP 连接需要底层 IP 协议来寻址网络中的主机。我们知道网络层使用的 IP 协议可以帮助我们根据 IP 地址来找到目标主机,但是一台主机上可能运行着多个应用程序,如何才能与指定的应用程序通信就要通过 TCP 或 UPD 的地址也就是端口号来指定。这样就可以通过一个 Socket 实例唯一代表一个主机上的一个应用程序的通信链路了。



WebSocket详解(六):刨根问底WebSocket与Socket的关系_4.gif

WebSocket详解(六):刨根问底WebSocket与Socket的关系_5.gif

而 WebSocket 则不同,它是一个完整的 应用层协议,包含一套标准的 API

所以,从使用上来说,WebSocket 更易用,而 Socket 更灵活。

10、最后提一下 HTML5 与 WebSocket 的关系


WebSocket APIHTML5 标准的一部分, 但这并不代表 WebSocket 一定要用在 HTML 中,或者只能在基于浏览器的应用程序中使用。

实际上,许多语言、框架和服务器都提供了 WebSocket 支持,例如:


附录:其它Web端即时通讯技术文章


新手入门贴:史上最全Web端即时通讯技术原理详解
Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
SSE技术详解:一种全新的HTML5服务器推送事件技术
Comet技术详解:基于HTTP长连接的Web端实时通信技术
新手快速入门:WebSocket简明教程
socket.io实现消息推送的一点实践及思路
LinkedIn的Web端即时通讯实践:实现单机几十万条长连接
Web端即时通讯技术的发展与WebSocket、Socket.io的技术实践
Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)
开源框架Pomelo实践:搭建Web端高性能分布式IM聊天服务器
使用WebSocket和SSE技术实现Web端消息推送
详解Web端通信方式的演进:从Ajax、JSONP 到 SSE、Websocket
MobileIMSDK-Web的网络层框架为何使用的是Socket.io而不是Netty?
>> 更多同类文章 ……

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

本帖已收录至以下技术专辑

推荐方案
评论 17
WebSocket如果能像http这样被用的这么极致,估计Web应用在某些方面会更牛逼,期待!
签名: 秋天到了,终于凉快了
这篇文章正是我想要的,大赞!
签名: 该会员没有填写今日想说内容.
看的不是很懂,还是很大收获
引用:605682883 发表于 2018-10-25 18:54
看的不是很懂,还是很大收获

哪里不懂?
想问一下,WebSocket是应用层协议,建立的时候会多走一次http请求,但是之后发送数据也是直接通过tcp传输,
我看我们购买的源码里是直接使用socket的,但是要自己处理半包问题,如果直接使用websocket的话,也可以在连接建立的时候对身份做一些验证,就不需要通过消息的形式验证身份了,
与直接使用Socket自己去封装协议,两者的处理效率差异大吗?
引用:溺水的小青蛙 发表于 2021-06-28 18:26
想问一下,WebSocket是应用层协议,建立的时候会多走一次http请求,但是之后发送数据也是直接通过tcp传输, ...

你的意思是你买的代码,在App端用websocket作为底层通信协议,而不是直接用TCP?
引用:JackJiang 发表于 2021-06-28 21:30
你的意思是你买的代码,在App端用websocket作为底层通信协议,而不是直接用TCP?

嗯 我是想换底层直接使用websocket,不过不知道会不会在效率方面不如直接使用socket,毕竟一个是应用层的协议,一个属于是直接调用传输层
引用:溺水的小青蛙 发表于 2021-06-29 09:02
嗯 我是想换底层直接使用websocket,不过不知道会不会在效率方面不如直接使用socket,毕竟一个是应用层的 ...

回答你的问题很简单,WebSocket这个组合词,前面那3个字母啥意思?你体会一下就有答案了
引用:JackJiang 发表于 2021-06-29 09:17
回答你的问题很简单,WebSocket这个组合词,前面那3个字母啥意思?你体会一下就有答案了

我的理解是这样的:早期大家都是使用socket,经过自己的逻辑封装做底层通讯协议,然后h5的大佬制定了一套通用的协议,命名为websocket,使得大家可以快速上手tcp长连接,后来不止h5,各端都开始支持这套协议,就像短连接都遵循http协议这样。
也不知道我的理解对不对,因为使用websocket的话,app也是支持的,web端也会容易开发一些,但是如果是处理起来效率不如直接使用socket的话,还是要用socket的,现在属于选型阶段。
引用:JackJiang 发表于 2021-06-29 09:17
回答你的问题很简单,WebSocket这个组合词,前面那3个字母啥意思?你体会一下就有答案了

WebSocket API是 HTML5 标准的一部分, 但这并不代表 WebSocket 一定要用在 HTML 中,或者只能在基于浏览器的应用程序中使用,这个是文章里的内容,我觉得不能因为命名是web,就说明不适合用在app吧
引用:溺水的小青蛙 发表于 2021-06-29 14:58
WebSocket API是 HTML5 标准的一部分, 但这并不代表 WebSocket 一定要用在 HTML 中,或者只能在基于浏览 ...

我想表达的意思是,有更强大的(准确地说是更底层),技术资源(包括源码、资料)更丰富的,久经考验的tcp、udp,为什么要用才标准化没几年,连客户端的各种库都是开源或半开源的(你肯定也在找这些库)、未经大产品考验的东西,你干嘛非得去舍近求远啊。。。

web技术里用它,那是因为在它之前并没有真正的长连接技术,它就是为了解决这个问题而出现,而你富客户端不存在这些问题,用它的目的是啥呢。。。

我觉得app端用webscoket的,多数情况肯定不是因为websocket比更底层的tcp更好,而是因为手上没有技术积累,与其从tcp撸,而不如从看似更简单的webscoket开始,就是这个心态。而且,还能跟web端用同一种接入层。。。 貌似看起来真的很美 。。
引用:JackJiang 发表于 2021-06-29 21:15
我想表达的意思是,有更强大的(准确地说是更底层),技术资源(包括源码、资料)更丰富的,久经考验的tc ...

对,用websocket的话不需要去考虑半包粘包的策略了,其他倒也没什么不同,而且对刚接触长连接的开发来说,websocket确实好上手一些,其实服务端倒也没什么,两种都可以一起实现
引用:溺水的小青蛙 发表于 2021-06-30 14:49
对,用websocket的话不需要去考虑半包粘包的策略了,其他倒也没什么不同,而且对刚接触长连接的开发来说 ...

虽然我的 MobileIMSDK 里已经支持WebSocket,但你要让我把移动端也换成WebSocket去连,我肯定不干,跟WebSocket为了简单而简单的那点api相比,tcp的可操作空间大多了,并且各种场景久经考验。
引用:JackJiang 发表于 2021-06-30 15:11
虽然我的 MobileIMSDK  里已经支持WebSocket,但你要让我把移动端也换成WebSocket去连,我肯定不干,跟We ...

ok  这个我懂的  肯定越底层实现,可操作空间越大的,我们买的RainbowChat和MobileMSDK源码里,websocket那块还是待实现,是有版本了吗
引用:溺水的小青蛙 发表于 2021-06-30 16:14
ok  这个我懂的  肯定越底层实现,可操作空间越大的,我们买的RainbowChat和MobileMSDK源码里,websocket ...

是的,新版的MobileIMSDK里会有,但我还没有正式对外发布
引用:溺水的小青蛙 发表于 2021-06-29 09:02
嗯 我是想换底层直接使用websocket,不过不知道会不会在效率方面不如直接使用socket,毕竟一个是应用层的 ...

我和你的想法一样的,我也是用websocket做app的实时通信的,我觉得没有问题啊。tcp再强大,一我把握不住,二我不需要tcp的强大,我的场景很简单websocekt可以快速实现为什么不用?那有tcp为什么还要用http?因为简单啊,有tcp为什么要用websocket,因为简单啊
至于效率问题,你自己封装个协议,就算比websocket效率高个数量级,但你有多大并发,多大数据量?所以我觉得一般情况下app用websocket肯定没有问题
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部