python websocket服务器端_python实现websocket服务器

b6247b6f7185eca25edf8c5257452f3d.png

websocket是什么呢,websocket是一个和服务器通信的新的协议,一般而言,浏览器和服务器通信最常用的是http协议,但是http协议是无状态的,每次浏览器请求信息,服务器返回信息后这个浏览器和服务器通信的信道就被关闭了,这样使得服务器如果想主动给浏览器发送信息变得不可能了,服务器推技术在http时代的解决方案一个是客户端去轮询,或是使用comet技术,而websocket则和一般的socket一样,使得浏览器和服务器建立了一个双工的通道。

具体的websocket协议在rfc6455里面有,这里简要说明一下。websocket通信需要先有个握手的过程,使得协议由http转变为webscoket协议,然后浏览器和服务器就可以利用这个socket来通信了。

首先浏览器发送握手信息,要求协议转变为websocket

get / http/1.1

host: example.com

upgrade: websocket

connection: upgrade

sec-websocket-key: dghlihnhbxbszsbub25jzq==

origin:

服务器接收到信息后,取得其中的sec-websocket-key,将他和一个固定的字符串258eafa5-e914-47da-95ca-c5ab0dc85b11做拼接,得到的字符串先用sha1做一下转换,再用base64转换一下,就得到了回应的字符串,这样服务器端发送回的消息是这样的

http/1.1 101 switching protocols

upgrade: websocket

connection: upgrade

sec-websocket-accept: s3pplmbitxaq9kygzzhzrbk+xoo=

这样握手就完成了,用python来实现这段握手过程的话就是下面这样。

defhandshake(conn):

key =none

data = conn.recv(8192)

ifnotlen(data):

returnfalse

forlineindata.split('\r\n\r\n')[0].split('\r\n')[1:]:

k, v = line.split(': ')

ifk =='sec-websocket-key':

key =base64.b64encode(hashlib.sha1(v +'258eafa5-e914-47da-95ca-c5ab0dc85b11').digest())

ifnotkey:

conn.close()

returnfalse

response ='http/1.1 101 switching protocols\r\n'\

'upgrade: websocket\r\n'\

'connection: upgrade\r\n'\

'sec-websocket-accept:'+ key +'\r\n\r\n'

conn.send(response)

returntrue

握手过程完成之后就是信息传输了,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 ...                |

+---------------------------------------------------------------+

值得注意的是payload len这项,表示数据的长度有多少,如果小于126,那么payload len就是数据的长度,如果是126那么接下来2个字节是数据长度,如果是127表示接下来8个字节是数据长度,然后后面会有四个字节的mask,真实数据要由payload data和mask做异或才能得到,这样就可以得到数据了。发送数据的格式和接受的数据类似,具体细节可以去参考rfc6455,这里就不过多赘述了。

然后在我的github上有我实现的websocket server的代码,简单使用的话是足够了,但是如果是作为应用还是需要把所有的协议的具体细节都去实现才可以。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页

打赏作者

飞鸡壳壳

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值