关于websocket 参考: websocket
关于http请求,请参考: HTTP中Post的multipart/form-data请求分析
关于tcp和三次握手请参考: 数据包报文格式(IP包、TCP报头、UDP报头) 和 TCP 三次握手和四次挥手 要按先后顺序
总结:
http和websocket 在浏览器和服务器经过三次握手建立tcp连接(通常不会发送额外的数据)。http会立即发送请求的内容。而websocket 则发送升级协议,我们通常称之为第四次握手。
他们首次发送的数据都是http请求的格式。不能通过 socket 帧包进行解析。
http
GET http://127.0.0.1:9999/inde?a=b HTTP/1.1
Host: 127.0.0.1:9999
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="104", " Not A;Brand";v="99", "Microsoft Edge";v="104"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 Edg/104.0.1293.70
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
----------------------结束线为了完美说明上面两个空行也是http协议的一部分-----------------------------------------------------------
websocket
GET http://127.0.0.1:9999/ HTTP/1.1
Host: 127.0.0.1:9999
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 Edg/104.0.1293.70
Upgrade: websocket
Origin: null
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Sec-WebSocket-Key: T5t/sn7K1aW/n7Z5MqLNig==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: chat, chat1
----------------------结束线为了完美说明上面两个空行也是http协议的一部分-----------------------------------------------------------
他们共同遵守同一个格式
实际上我认为它们第一次发送的都是http请求,只不过服务器的解析方式不同。
服务器应该如何解析呢?按行读取,创建 header。遇到空行代表这header读取完毕。 通过header里的Content-Length 来读取Request Body的数据(读取的是byte,不是字符)。然后判断是否有协议升级。
websocket协议升级后,不能关闭socket,要保持。对于http,进行响应后关闭连接即可。
websocket从第二次发送数据就开始使用如下图所示的数据包帧,需要解包进行消息数据的读取
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
包格式的含义见 websocket 部分。
对于socket的用法我们这里就不在赘述了,各大语言里都有相关的技术文档。
本文链接:https://blog.nnwk.net/article/132
有问题请留言。版权所有,转载请在显眼位置处保留文章出处,并留下原文连接
Leave your question and I'll get back to you as soon as I see it. All rights reserved. Please keep the source and links
友情链接:
子卿全栈
全部评论