上方蓝色“程序员追风”,选择“设为星标”
回复“资料”获取整理好的面试资料
原文:juejin.cn/post/6942358900171603975
Socket 是什么?
-
TPC/IP 协议是传输层协议,主要解决数据如何在网络中传输;
-
Socket 是对 TCP/IP 协议的封装和应用 (程序员层面上);
-
而 HTTP 是应用层协议,主要解决如何包装数据。
TCP/IP 和 HTTP 协议的关系是: “我们在传输数据时,可以只使用 (传输层)TCP/IP 协议,但是那样的话,如果没有应用层,便无法识别数据内容。如果想要使传输的数据有意义,则必须使用到应用层协议。应用层协议有很多,比如 HTTP、FTP、TELNET 等,也可以自己定义应用层协议。WEB 使用 HTTP 协议作应用层协议,以封装 HTTP 文本信息,然后使用 TCP/IP 做传输层协议将它发到网络上。”
Socket 是什么呢,实际上 socket 是对 TCP/IP 协议的封装,Socket 本身并不是协议,而是一个调用接口 (API)。通过 Socket,我们才能使用 TCP/IP 协议。
Socket 跟 TCP/IP 协议关系是: “TCP/IP 只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口。这个就像操作系统会提供标准的编程接口,比如 win32 编程接口一样,TCP/IP 也要提供可供程序员做网络开发所用的接口,这就是 Socket 编程接口。”
从上图中可以看到,HTTP 是基于传输层的 TCP 协议的,而 Socket API 也是,所以只是从使用上说,可以认为 Socket 和 HTTP 类似(但一个是成文的互联网协议,一个是一直沿用的一种编程概念),是对于传输层协议的另一种直接使用,因为按照设计,网络对用户的接口都应该在应用层。
WebSocket 协议的来源:
WebSocket 属于 WHATWG 发布的 Web Application 的一部分(即 HTML5)的产物。大约在 08 年的时候,WG 的工程师在讨论网络环境中需要一种全双工的连接形式,刚开始一直叫做「TCPConnection」,并讨论了这种协议需要支持的功能,大致已经和我们今天看到的 WebSocket 差不多了。他们认为基于现有的 HTTP 之上的一些技术(如长轮询、Comet)并满足不了这种需求,有必要定义一个全新的协议。
WebSocket 协议的开篇就说,本协议的目的是为了解决基于浏览器的程序需要拉取资源时必须发起多个 HTTP 请求和长时间的轮训的问题…… 而创建的。
WebSocket 和 Socket 的区别?
两者没什么关系,就像雷锋跟雷锋塔一样。
为什么要使用 Websocket?
WebSocket 的目的就是解决网络传输中的双向通信的问题,HTTP1.1 默认使用持久连接(persistent connection
),在一个 TCP 连接上也可以传输多个Request/Response
消息对,但是 HTTP 的基本模型还是一个 Request 对应一个 Response。
这在双向通信(客户端要向服务器传送数据,同时服务器也需要实时的向客户端传送信息,一个聊天系统就是典型的双向通信)时一般会使用这样几种解决方案:
-
轮询(polling),轮询就会造成对网络和通信双方的资源的浪费,且非实时。
-
长轮询,客户端发送一个超时时间很长的 Request,服务器 hold 住这个连接,在有新数据到达时返回 Response,相比 #1,占用的网络带宽少了,其他类似。
-
长连接,其实有些人对长连接的概念是模糊不清的,我这里讲的其实是 HTTP 的长连接(1)。如果你使用 Socket 来建立 TCP 的长连接(2),那么,这个长连接(2)跟我们这里要讨论的 WebSocket 是一样的,实际上 TCP 长连接就是 WebSocket 的基础,但是如果是 HTTP 的长连接,本质上还是 Request/Response 消息对,仍然会造成资源的浪费、实时性不强等问题。
Websocket 协议内容
WebSocket 的目的是取代 HTTP 在双向通信场景下的使用,而且它的实现方式有些也是基于 HTTP 的(WS 的默认端口是 80 和 443)。现有的网络环境(客户端、服务器、网络中间人、代理等)对 HTTP 都有很好的支持,所以这样做可以充分利用现有的 HTTP 的基础设施,有点向下兼容的意味。
WS 协议有两部分组成:握手和数据传输。
握手
使用 Http 进行实现。由客户端使用 http 的方式发起握手请求,服务端接请求后,将当前正在使用的连接(TCP)的协议,由 http 协议切换为 websocket 协议。
握手请求头会带有 Upgrade 参数用于升级协议类型:
Upgrade: upgrade 是 HTTP1.1 中用于定义转换协议的 header 域。它表示,如果服务器支持的话,客户端希望使用现有的「网络层」已经建立好的这个「连接(此处是 TCP 连接)」,切换到另外一个「应用层」(此处是 WebSocket)协议。
Upgrade 扩展:Upgrade 是 HTTP 中用来进行协议升级的头域,在扩展的协议内容中,客户端发起的协议转换的方式更多,同时服务器也可以选择不接受客户端的协议升级请求;服务端也可以发起协议升级。
请求 uri 格式:
ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]
host = <host, defined in [RFC3986], Section 3.2.2>
port = <port, defined in [RFC3986], Section 3.2.3>
path = <path-abempty, defined in [RFC3986], Section 3.3>
query = <query, defined in [RFC3986], Section 3.4>
数据传输
服务端接收握手请求后,回复 response 消息,一旦这个握手回复发出去,服务端就认为此 WebSocket 连接已经建立成功,处于 OPEN 状态。它就可以开始发送数据了。
WebSocket 中所有发送的数据使用帧的形式发送。客户端发送的数据帧都要经过掩码处理,服务端发送的所有数据帧都不能经过掩码处理。否则对方需要发送关闭帧。
一个帧包含一个帧类型的标识码,一个负载长度,和负载。负载包括扩展内容和应用内容。
WebSocket 和 HTTP 的对比
相同点
-
都是基于 TCP 的应用层协议。
-
都使用 Request/Response 模型进行连接的建立。
-
在连接的建立过程中对错误的处理方式相同,在这个阶段 WS 可能返回和 HTTP 相同的返回码。
-
都可以在网络中传输数据。
不同点
-
WS 使用 HTTP 来建立连接,但是定义了一系列新的 header 域,这些域在 HTTP 中并不会使用。
-
WS 的连接不能通过中间人来转发,它必须是一个直接连接。
-
WS 连接建立之后,通信双方都可以在任何时刻向另一方发送数据。
-
WS 连接建立之后,数据的传输使用帧来传递,不再需要 Request 消息。
-
WS 的数据帧有序。
你在看吗