共计 3209 个字符,预计需要花费 9 分钟才能阅读完成。
1.HTTP
HTTP 是超文本传输协定,英文写作 HyperText Transfer Protocol,它是构建在 TCP 协定之上的。
在 http 的两端别离是客户端和服务器,这就是经典的 B / S 模式。另外,这里的 B,就是浏览器的意思,浏览器成为了 http 的代理,用户的行为将会通过浏览器转化为 http 申请报文,发送给服务器,服务器也就是 S,会解决申请,而后发送响应报文给代理,也就是浏览器,浏览器解析响应报文后,将用户界面展现给用户。这里咱们看到,基于 http 或者 https 的 B / S 模式中国,浏览器只负责发送报文、接管报文、解析报文、展现界面,服务器负责解决 http 申请和发送 http 响应。
TCP 全称为传输控制协议,在 OSI 模型上属于传输层协定。
七层协定示意图如下:
TCP 是面向连贯的协定,其显著特色是在传输之前须要 3 次握手造成会话。
只有会话造成后,服务器端和客户端能力互相发送数据。在创立会话的过程中,服务器端和客户端别离提供一个套接字,
这两个套接字独特造成一个连贯。服务器端和客户端则通过套接字实现两者之间连贯的操作。
http 网络通信的所有报文信息如下,报文分为四局部。
$ curl -v http://127.0.0.1:1337
// 第一局部:是经典的 TCP 三次握手,这样就建设了连贯
* About to connect() to 127.0.0.1 port 1337 (#0)
* Trying 127.0.0.1...
* connected
* Connected to 127.0.0.1 (127.0.0.1) port 1337 (#0)
// 第二局部:在实现握手之后,客户端向服务器端发送申请报文。> GET / HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5
> Host: 127.0.0.1:1337
> Accept: */*
>
// 第三局部: 服务器端实现解决后,向客户端发送的响应内容,包含响应头和响应体。< HTTP/1.1 200 OK
< Content-Type: text/plain
< Date: Sat, 06 Apr 2013 08:01:44 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
Hello World
第四局部:完结会话的信息
* Connection #0 to host 127.0.0.1 left intact
* Closing connection #0
留神:报文的内容次要是两局部,报文头和报文体,上一个例子中,应用的是 get 申请,报文头的局部是上边报文信息中 > 和 < 的局部。在响应报文中,有一个报文体,是 Hello World。
2.WebSocket
应用 websocket 的话,网页客户端只需一个 TCP 链接即可实现双向通信,在服务端与客户端频繁通信时,毋庸频繁断开连接和重发申请。连贯能够失去高效利用。
websocket 与 HTTP 有如下益处:
- 客户端与服务器只建设一个 tcp 连贯,能够应用更少的连贯
- websocket 服务器端能够推送数据到客户端,这远比 HTTP 申请响应模式更灵便,更高效。
- 有更轻量级的协定头,缩小数据传送量
相比 http,websocket 更靠近于传输层协定,它并没有在 http 的根底上模仿服务器端的推送,而是在 tcp 上定义独立的协定,然而 websocket 的握手局部是由 Http 实现的。
websocket 分为握手和数据传输两局部,其中握手应用了 http 进行。
1)WebSocket 握手
客户端建设连贯是,通过 HTTP 发动申请报文。如下所示:
GET /chat HTTP/1.1
Host: server.example.com
// 申请服务端降级协定为 WebSocket
Upgrade: websocket
Connection: Upgrade
// 用于平安校验
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
// 指定子协定和版本号
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
服务器端在解决完申请后,响应如下报文:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
这段报文将通知客户端,正在更换协定,更新为应用层协定 websocket,并在以后的套接字上利用新的协定。
残余的字段别离示意服务器端基于 Sec-WebSocket-Key 生成的字符串和选中的子协定。客户端将会校验 Sec-WebSocket-Accept 的值,如果胜利,将开始接下来的数据传输。
2)WebSocket 数据传输
在顺利握手后,以后连贯将不再进行 http 交互,而是开始 websocket 的数据帧协定,实现客户端与服务器的数据交换。
协定降级的过程如下:
当客户端调用 send()发送数据时,服务器端触发 onmessage(),当服务器端调用 send()发送数据时,客户端的 onmessage()触发,当咱们调用 send()发送一条数据时,协定可能将这个数据封装为一帧或多帧数据,而后逐帧发送。
为了平安思考,客户端须要发送的数据帧进行掩码解决,服务器一旦收到无掩码帧,比方两头拦挡毁坏,连贯将会敞开。服务器发送到客户端的数据帧无需做掩码,如果客户端收到了带掩码的数据帧,连贯也将敞开。
在 websocket 中的数据帧的定义,每 8 位为一列,也就是一个字节,其中每一位都有它的意义:
- fin,如果这一帧是最初一帧,这个 fin 为为 1,其余状况为 0.
- rsv1、rsv2、rsv3,都是一位长,用于标识扩大,当有已协商的扩大时,这些值可能为 1,其余状况为 0。
- opcode,4 位长,能够用来示意 0~15 的值,用于解释以后数据帧,0 示意附加数据帧,1 示意文本数据帧,2 示意二进制数据帧,8 示意发送一个连贯敞开的数据帧,9 示意 ping 数据帧,10 示意 pong 数据帧,其余值临时没有定义。瓶数据帧和 pong 数据帧用于心跳检测,当一端发送一个 ping 数据帧时,另一端必须发送 pong 数据帧作为回应,告知对方这一端依然处于响应状态。
- masked,示意是否进行掩码解决,1 位长度,客户端发送给服务器时为 1,服务器发送回客户端时为 0.
- payload length:一个 7、7+16 或 7 +64 位长的数据为,标识数据的长度,如果值在 0~125 之间那么该值就是数据的实在长度,如果是 126,则前面 16 位的值是数据的实在长度,如果是 127,则前面 64 位的值是数据的实在长度。
- making key,当 masked 为 1 时,这里是一个 32 位长的数据位,用于解密数据。
- payload data,咱们的指标数据,位数为 8 的倍数。
客户端发送音讯时,须要结构一个或多个数据帧协定报文,例如咱们发送一个 hello world,这个比拟短,不存在宰割多个数据帧的状况,并且以文本形式发送,他的 payload length 长度为 96(12 字节 * 8 位 / 字节),二进制示意为 110000。所以报文应该是:
fin(1) + res(000) + opcode(0001) + masked(1) + payload length(1100000) + masking key(32 位) + payload
data(hello world! 加密后的ܾ二进制)
服务器回复的是 yakexi,这个无需掩码,模式如下:
fin(1) + res(000) + opcode(0001) + masked(0) + payload length(1100000) + payload data(yakexi 的ܾ二进制)