WebSocket网络通信协议
WebSocket网络通信协议
网络部分的方向:
- 网络编程--->
socket编程,epoll,reactor--->主要解决一个server对应多个客户端(并发)- 网络协议--->
tcp,http,upd,https--->主要解决一个客户端与一个server之间通信的时候传输的数据格式(协议头、协议内容、ip头、不同场景如何)
WebSocket相关内容
特点:
- 基于
tcp的协议--->主要解决多个客户端一个服务器传输数据过程中的粘包的问题
说明:
tcp协议的特点--->流式套接字(buffer,特点:我发数据对方肯定能收到,对方发数据我也能收到.先发的数据先收到)--->数据必达性,数据顺序不乱
场景举例:
客户端发送两个包(package1、package2),服务端只调用了一次rec(fd, buffer, length, 0)就全部接收到了.
问题:
buffer当中包含了两个包的数据,服务端如何去区别buffer当中是两个包数据还是一个包数据
所有tcp的应用协议需要解决的问题:
- 如何分包(
tcp只做到了数据必达以及先发先收) - 发送明文还是密文(
RSA非对称还是对称)
解决办法:
- 定义长度(
length) - 做一个分隔符
WebScoket核心:
- 解决粘包的问题--->基于
tcp的应用协议解决的问题就是如何粘包 - 应用于业务场景的时候,因为
websocket只做了如何解决粘包的处理(传输是否是明文...),所以还需要加上一层关于业务场景定义的协议(里面传的数据格式与websocket无关(比如传json、xml什么的))
协议说明:
例如:https://www.baidu.com或sw://192.168.x.x:8888
xxx://说明的是协议--->使用什么协议访问资源www.baidu.com--->域名或者主机(去DNS上面找到对应的域名访问)- 在下面的
/后面的内容--->访问哪个location--->访问什么资源
翻译:
采用什么协议访问哪台机器的哪个资源?
内容发送解析:
request什么时候发送?--->握手handshake(这里面没有6字节的字节头,因为是基于tcp协议去做的)
客户端点击连接--->调用connect三次握手完成之后(建立好了连接),调用send(fd, buffer, length, 0)--->这就是客户端的request(实现websocket客户端的时候也就是定义好request的内容)
websocket头--->发送数据、接收数据
http、https协议在发送数据的时候都会有一个协议头,协议头后面跟着的才传输内容,同样websocket协议也有websocket协议头--->长度为6位
- 断开连接
服务端会接收到6位长度的字节头,里面不带数据
任何一个协议设计都要设计好上述三个环节
WebSocket连接细节自问自答
- 为什么要握手?--->
websocket基于tcp,为什么websocket在tcp的连接之上还需要一个握手?
tcp协议中客户端和服务器已经建立好连接了.websocket为什么还要建立握手?
握手解决的问题:
- 客户端和服务器有多个协议,那么就有多个协议的版本.可以通过握手解决连接走哪个版本的协议
也可以在发送协议的时候每一个数据包前4bit都是协议版本--->握手的好处是不需要每一个数据包都确定是哪个协议
- 兼容
http、https协议
websocket协议首先是要兼容web的协议,也就是http和https协议,那么websocket当中的tcp协议就做到了这一点,所以websocket要在tcp连接之后在发送握手协议
- 验证双方的身份是否合法
关注编码
web验证身份--->authority
webscoket验证身份--->Sec-WebSocket-Key(字符串末尾有等号或者多个等号(base64编码))--->服务端根据发送的sec-websocket-key转换成sec-websocket-accept,客户端接接收到response的accept以后去和key比对,不符合就会断开连接
注意:
协议当中没有定义key的长度,所以需要GUID,这个GUID起到的是填充的作用,因为accept需要用key做SHA-1 hash运算
- 为什么要断开?--->
tcp连接也可以检查出已经断开连接,websocket为什么还要做一次断开?
websocket在tcp之上还做了一次断开
WebSocket两个难点
- 哪里体现出来使用的是
websocket协议?
Upgrade: websocket
- 如何进行双方身份验证?
使用Sec-WebSocket-Key加上GUID进行SHA-1 Hash运算,得到Accept
WebScokect协议在HandShake的时候和传输数据的时候为什么字节头不一样
HandShake是基于tcp协议进行的三次握手,所以没有6字节的字节头
WebSocket协议传输字节图:
分析:--->最上面0、1、2、3是byte字节,0、1、2、3、4、5、6...是bit
- 一共有
32个bit长度,四个字节(一个字节8bit)--->看上述图要上下看,Payload Data是数据,前面的是协议头
测试当中为什么会有边界值一说?
因为在传输协议当中,如果传输的数据内容长度不足一定程度的话他的协议头占用的字节会不一样,在websocket协议中,payload长度不足126,那么实际的协议头只有1字节的opetioncode操作码,1字节长度4字节掩码(总共6字节)
if (payloadLength < 126)
{
sizeof websocketshake = 6; // 六字节
}else if (payloadLength == 126)
{
sizeof websocketshake = 8; // 八字节
}else {
sizeof websocketshake = 14; // 十四字节()
}// payloadLength长度要看`bit`的长度
由上述表可以看出,payloadLength长度最长是7+64bit
10bit--->K,20bit--->M,30bit--->G,40bit--->T,50bit--P...



浙公网安备 33010602011771号