百度内推,可文末扫码加微信
websocket,顾名思义就是web端的socket,其作用就是给web端提供了与httpserver端之间的长连接,使得httpserver在建立连接的任何时候都可以主动通知web页面事件,如果没有此协议存在的话,web端需要不断的通过轮询的方式去查询一些服务器端的状态。websocket的之下使用的是我们传输层的tcp协议,我们知道任何通信协议都有其协议规则,只要搞清楚了其协议内容就可以知道怎么运用协议进行编程,章节2就是websocket协议整个内容及详解。
websocket的整个协议内容如图1所示:
想要实现此协议,我们需要弄明白协议中每个字段的作用,下面对每个字段做详细介绍。
FIN : 占1位,数据是否已经发送完成的标志,如为1,表示负载数据是全部数据已经收齐,如为0,表示负载数据还未收齐,需要继续收接下来的数据。
RSV1-RSV3:各占一位,预留字段,为留作后续扩展使用。
操作码:占4位,用来标识后续负载是什么类型的数据,常用操作码:
①0x0 码表示是连续数据帧,接收端需要不断接受0x0码标识的负载数据直到FIN变为1;
②0x1 码表示是文本数据
③0x2 码表示是二进制数据
④0x9 码是ping,与pong一起来维护心跳的数据。
⑤0xa 码是pong,与ping一起来维护心跳的数据。
⑥0x8 码是一方主动关闭websocket的时候发送的数据。
MASK:占1位,是否开启掩码的标志,如为1,表示开启掩码运算,如为0,表示不开启掩码运算,这里客户端必须要开启掩码,即必须设置为1。这里的掩码运算是将负载中的数据与掩码值做 异或运算以得出真实的数据。
负载长度:占7位,如果负载长度小于126,则表示负载数据的实际大小;如果等于126,则表示有扩展负载长度字段,且扩展长度字段占16位;如果等于127,则表示有扩展负载长度字段,且 扩展负载字段占64位。如果有扩展负载字段,那么扩展负载字段才是真正的负载数据大小。
扩展负载长度:占0位或16或64位,占位大小取决于上述负载长度的大小。负载长度小于126,占0位,无扩展负载长度;负载长度等于126,扩展负载长度占16位;负载长度等于127,扩展负 载长度占64位。与负载长度字段一起标识了负载数据的实际大小。
掩码值:占32位,要参与掩码运算的值,在MASK位置1的前提下有效,且客户端发送过来的websocket数据一定是带有掩码值的。
负载数据:负载数据的实际占位大小由上述的负载长度和扩展负载长度共同决定。有效数据在此存放。
注意:上述内容在编程的时候要注意的内容如下:
①FIN字段,每次在接收完数据后要判断FIN是否为1,不为1要继续收数据
②MASK字段,如果是客户端该字段必须为1,否则接收到客户端为非1的MASK数据直接丢弃。
③负载数据长度是由负载长度和扩展负载长度共同决定的,是在动态变化的,在编程时先计算负载长度大小,由负载长度的大小才能计算出实际的负载数据长度。
④掩码值是用来对有效数据进行编码的,服务器端在收到之后必须对有效数据进行解码,解码的算法其实就是一个简单的异或运算。
websocket在建立连接的时候首先是发送的http请求进行握手,握手请求成功之后就会变成长连接进行普通的socket通信。具体步骤如下:
①客户端(网页)发起http握手请求,请求内容如下:
GET /chat HTTP/1.1 (http请求行,GET方法,协议是http1.1版本)
Host: example.com:8000 (请求头,指定访问的主机,这里假设是example.com:8000)
Upgrade: websocket (升级协议为websocket)
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== (websocket key)
Sec-WebSocket-Version: 13
②服务器收到握手请求后应答如下:
HTTP/1.1 101 Switching Protocols (应答行,协议是http1.1版本)
Upgrade: websocket (升级协议为websocket)
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= (该字段是请求中Sec-WebSocket-Key经过sha签名然后base64编码之后的内容)
③若上述都成功后则建立起普通的socket长连接,这个时候不论是服务器还是客户端都可以给对方在任意时刻发送数据。
扫一扫,可加楼主微信,一起交流C语言,嵌入式等IT技术。