以前总结了关于Websocket协议的握手链接方式等其余细节,如今对socket链接创建后的数据帧传输和关闭细节总结。web
数据传输使用的是一系列数据帧,出于安全考虑和避免网络截获,客户端发送的数据帧必须进行掩码处理后才能发送到服务器,不管是否是在TLS安全协议上都要进行掩码处理。服务器若是没有收到掩码处理的数据帧时应该关闭链接,发送一个1002的状态码。服务器不能将发送到客户端的数据进行掩码处理,若是客户端收到掩码处理的数据帧必须关闭链接。算法
基本的数据帧为一个opcode、一个payload长度和发送的应用数据,根据ABNF的定义,详细信息以下图缓存
这里使用的是数据存储的位(bit),当进行加密的时候,最终要的一位就是最左边的第一个。安全
Masking-key域的数据便是掩码密钥,用于解码PayloadData。客户端发出的数据帧须要进行掩码处理,因此此位是1。
分片目的是发送长度未知的消息。若是不分片发送,即一帧,就须要缓存整个消息,计算其长度,构建frame并发送;使用分片的话,可以使用一个大小合适的buffer,用消息内容填充buffer,填满即发送出去。服务器
分片规则:websocket
1.一个未分片的消息只有一帧(FIN为1,opcode非0)网络
2.一个分片的消息由起始帧(FIN为0,opcode非0),若干(0个或多个)帧(FIN为0,opcode为0),结束帧(FIN为1,opcode为0)。并发
3.控制帧能够出如今分片消息中间,但控制帧自己不容许分片。socket
4.分片消息必须按次序逐帧发送。加密
5.若是未协商扩展的状况下,两个分片消息的帧之间不容许交错。
6.可以处理存在于分片消息帧之间的控制帧
7.发送端为非控制消息构建长度任意的分片
8.client和server兼容接收分片消息与非分片消息
9.控制帧不容许分片,中间媒介不容许改变分片结构(即为控制帧分片)
10.若是使用保留位,中间媒介不知道其值表示的含义,那么中间媒介不容许改变消息的分片结构
11.若是协商扩展,中间媒介不知道,那么中间媒介不容许改变消息的分片结构,一样地,若是中间媒介不了解一个链接的握手信息,也不容许改变该链接的消息的分片结构
12.因为上述规则,一个消息的全部分片是同一数据类型(由第一个分片的opcode定义)的数据。由于控制帧不容许分片,因此一个消息的全部分片的数据类型是文本、二进制、opcode保留类型中的一种。
须要注意的是,若是控制帧不容许夹杂在一个消息的分片之间,延迟会较大,好比说当前正在传输一个较大的消息,此时的ping必须等待消息传输完成,才能发送出去,会致使较大的延迟。为了不相似问题,须要容许控制帧夹杂在消息分片之间。
数据帧示例:
未掩码处理的文本单数据帧: 0x81 0x05 0x48 0x65 0x6c 0x6c 0x6f (contains "Hello")
掩码处理的文本单数据帧: 0x81 0x85 0x37 0xfa 0x21 0x3d 0x7f 0x9f 0x4d 0x51 0x58
分片未掩码处理的文本消息: 0x01 0x03 0x48 0x65 0x6c (contains "Hel")
0x80 0x02 0x6c 0x6f (contains "lo")
未掩码处理的Ping请求和掩码处理的响应:
0x89 0x05 0x48 0x65 0x6c 0x6c 0x6f (contains a body of "Hello", but the contents of the body are arbitrary)
0x8a 0x85 0x37 0xfa 0x21 0x3d 0x7f 0x9f 0x4d 0x51 0x58 (contains a body of "Hello", matching the body of the ping)
64K的二进制数据:0x82 0x7F 0x0000000000010000 [65536 bytes of binary data]
为了接收WebSocket数据,端点监听底层网络链接。传入数据必须解析为WebSocket帧。当接收到一个数据帧时,端点必须注意由操做码(帧-opcode)定义的数据的/type/。这个帧的“应用数据”被定义为消息的/data/。若是帧由一个未分片的消息组成,这是说已经接收到一个WebSocket消息,其类型为/type/且数据为/data/。若是帧是一个分片消息的一部分,随后数据帧的“应用数据”链接在一块儿造成/data/。当接收到由FIN位(帧-fin)指示的最后的片断时,这是说已经接收到一个WebSocket消息,其数据为/data/(由连续片断的“应用数据”组成)且类型为/type/(分配消息的第一个帧指出)。随后的数据帧必须被解释为属于一个新的WebSocket消息。
扩展能够改变数据如何读的语义,尤为包括什么组成一个消息的边界。扩展,除了在负载中的“应用数据”以前添加“扩展数据”外,也能够修改“应用数据”(例如压缩它)。服务器必须为从客户端接收到的数据帧移除掩码。
通讯的两端中任意一端关闭均可以关闭socket链接,关闭时应该清楚全部的TCP链接资源和TLS回话的资源,同时要丢弃全部的可能接收的字节数据。首先关闭的一方通常都应该是服务器端,而后处于TIME_WAIT状态。
为了使用一个状态码关闭websocket,一端必须发送一个关闭的控制帧,当两端都发送了关闭数据帧时,双方都要关闭全部的链接资源。控制帧为一个“状态码”和一个“缘由说明”,当关闭以后,双方处于CLOSED状态。