关于 websocket 的一些学习

WebSocket 用于在 Web 浏览器和服务器之间进行任意的双向数据传输的一种技术。WebSocket 协议(位于应用层)基于 TCP 协议实现,包含初始的握手过程,以及后续的多次数据帧双向传输过程。其目的是在 WebSocket 应用和 WebSocket 服务器进行频繁双向通信时,可以使服务器避免打开多个 HTTP 连接进行工作来节约资源,提高了工作效率和资源利用率。

其他特点包括:

(1)建立在 TCP 协议之上,服务器端的实现比较容易。

(2)与 HTTP 协议有着良好的兼容性。默认端口也是 80 和 443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据。

(5)没有同源限制,客户端可以与任意服务器通信。

(6)协议标识符是 ws(如果加密,则为 wss),服务器网址就是 URL。

文章参考:

注:上面第一个和第二个链接的文章被删了( Ĭ ^ Ĭ ),这告诉我们写文章时,尽量引用过来,不然别人的文章随时会被删掉

附上新的类似文章参考:

摘取一些比较重要的部分,

一、WebSocket 和 HTTP 之间的关系

WebSocket 和 HTTP 一样都是基于 TCP 的应用层协议。
WebSocket 协议和 HTTP 协议是两种不同的东西。客户端开始建立 WebSocket 连接时要发送一个 header 标记了 Upgrade 的 HTTP 请求,表示请求协议升级。所以服务器端做出响应的简便方法是,直接在现有的 HTTP 服务器软件和现有的端口上实现 WebSocket 协议,然后再回一个状态码为 101 的 HTTP 响应完成握手,再往后发送数据时就没 HTTP 的事了。也就是说 WebSocket 只是使用 HTTP 协议来完成一部分握手。

二、握手

握手部分的设计目的就是兼容现有的基于 HTTP 的服务端组件(web 服务器软件)或者中间件(代理服务器软件)。这样一个端口就可以同时接受普通的 HTTP 请求或 WebSocket 请求了。为了这个目的,WebSocket 客户端的握手是一个 HTTP 升级版的请求(HTTP Upgrade request):

客户端发送一个请求

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
 

这段类似 HTTP 协议的握手请求中多了以下几个东西

Upgrade: websocket
Connection: Upgrade

是告诉服务器我想升级为 websocket 协议

Sec-WebSocket-Key 是一个 Base64 加密的密钥
Sec-WebSocket-Protocol 是用于标识客户端想和服务端使用哪一种子协议(都是应用层的协议,比如 chat 表示采用 “聊天” 这个应用层协议)。
Sec-WebSocket-Version 是告诉服务器所使用的协议版本
Origin Origin 可以预防在浏览器中运行的脚本,在未经 WebSocket 服务器允许的情况下,对其发送跨域的请求。浏览器脚本在使用浏览器提供的 WebSocket 接口对一个 WebSocket 服务发起连接请求时,浏览器会在请求的 Origin 中标识出发出请求的脚本所属的源,然后 WebSocket 在接受到浏览器的连接请求之后,就可以根据其中的源去选择是否接受当前的请求。

比如我们有一个 WebSocket 服务运行在 http://websocket.example.com,然后你打开一个网页 http://another.example.com,在个 another 的页面中,有一段脚本试图向我们的 WebSocket 服务发起链接,那么浏览器在其请求的头中,就会标注请求的源为 http://another.example.com,这样我们就可以在自己的服务中选择接收或者拒绝该请求。

服务端响应

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

上面提到了这个 101 是状态码,websocket 是使用 HTTP 协议的 101 状态码进行协议切换。

Sec-WebSocket-Accept 这个值表示服务器同意握手建立连接,是客户端传输过来的 Sec-WebSocket-Key 跟 “258EAFA5-E914-47DA-95CA-C5AB0DC85B11” 拼接后,用 SHA-1 加密,并进行 BASE-64 编码得来的,Sha1(Sec-WebSocket-Key+258EAFA5-E914-47DA-95CA-C5AB0DC85B11)。

客户端收到 Sec-WebSocket-Accept 后,将本地的 Sec-WebSocket-Key 进行同样的编码,然后比对。

注:Switching Protocols 可能与 WebSockets 一起使用。


Boost C++ 库 Asio,它是异步输入输出的核心。 名字本身就说明了一切:Asio 意即异步输入/输出。 该库可以让 C++ 异步地处理数据,且平台独立。 异步数据处理就是指,任务触发后不需要等待它们完成。 相反,Boost.Asio 会在任务完成时触发一个应用。 异步任务的主要优点在于,在等待任务完成时不需要阻塞应用程序,可以去执行其它任务。

异步任务的典型例子是网络应用。 如果数据被发送出去了,比如发送至 Internet,通常需要知道数据是否发送成功。 如果没有一个像 Boost.Asio 这样的库,就必须对函数的返回值进行求值。 但是,这就要求在所有数据发送完之后,才能得到一个确认或错误代码。 而使用 Boost.Asio,这个过程被分为两个单独的步骤:第一步是作为一个异步任务开始数据传输。 一旦传输完成,不论成功或是错误,应用程序都会在第二步中得到关于相应的结果通知。 主要的区别在于,应用程序无需阻塞至传输完成,而可以在这段时间里执行其它操作。

WebSocketPP 是一个 C++ 库,实现了 WebSocket 客户端和服务器功能。它是一个建立在 Asio 之上的异步应用程序。

可以这样说,WebSocketPP 库将 Asio 和 websocket 技术融合在一起,我们直接用该库即可实现相应的数据异步传输。

 

端口号的作用主要是区分服务类别和在同一时间进行多个会话,比如服务器设置下发的端口号为 ::9002,如果客户端想要监听来自服务器的消息,就可以设置监听端口为 9002

web_socket_server_.listen(9002);

参考:端口号的作用及常见端口号用途说明

           C++项目中的extern "C" {}


 

websocket 客户端搭建:

原文链接: https://www.cnblogs.com/strive-sun/p/15062740.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    关于 websocket 的一些学习

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/404618

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月25日 下午4:39
下一篇 2023年4月25日 下午4:39

相关推荐