我是靠谱客的博主 自然冬瓜,最近开发中收集的这篇文章主要介绍基于socket实现websocket服务,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

websocket原理

首先,Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说。

HTTP的生命周期通过 Request 来界定,也就是一个 Request 一个 Response ,那么在 HTTP1.0 中,这次HTTP请求就结束了。

HTTP1.1中进行了改进,使得有一个keep-alive,也就是说,在一个HTTP连接中,可以发送多个Request,接收多个Response。但是请记住 Request = Response, 在HTTP中永远是这样,也就是说一个request只能有一个response。而且这个response也是被动的,不能主动发起。

Websocket是基于HTTP协议的,或者说借用了HTTP的协议来完成一部分握手。

首先我们来看个典型的 Websocket 握手

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13 Origin: http://example.com

熟悉HTTP的童鞋可能发现了,这段类似HTTP协议的握手请求中,多了几个东西。我会顺便讲解下作用。

Upgrade: websocket
Connection: Upgrade

这个就是Websocket的核心了,告诉 Apache 、 Nginx 等服务器:注意啦,我发起的是Websocket协议,快点帮我找到对应的助理处理~不是那个老土的HTTP。

Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Sec-WebSocket-Key 是一个 Base64 encode 的值,这个是浏览器随机生成的,告诉服务器:泥煤,不要忽悠窝,我要验证尼是不是真的是Websocket助理。

然后, Sec_WebSocket-Protocol 是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议

最后, Sec-WebSocket-Version 是告诉服务器所使用的 Websocket Draft (协议版本),在最初的时候,Websocket协议还在 Draft 阶段,各种奇奇怪怪的协议都有,而且还有很多期奇奇怪怪不同的东西,什么Firefox和Chrome用的不是一个版本之类的,后来做了统一。

然后服务器会返回下列东西,表示已经接受到请求, 成功建立Websocket啦!

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Sec-WebSocket-Protocol: chat

这里开始就是HTTP最后负责的区域了,告诉客户,我已经成功切换协议啦~

Upgrade: websocket
Connection: Upgrade

依然是固定的,告诉客户端即将升级的是 Websocket 协议,而不是mozillasocket,lurnarsocket或者shitsocket。

然后, Sec-WebSocket-Accept 这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key 。

后面的, Sec-WebSocket-Protocol 则是表示最终使用的协议。

至此,HTTP已经完成它所有工作了。

实例

<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>lujiacheng</h1>
<script>
ws=new WebSocket("ws://127.0.0.1:8096")
ws.onopen=function () {
alert('successful');
ws.send("Hellowww");
}
ws.onmessage=function (event) {
alert(event.data)
}
</script>
</body>
</html>
client.html
import socket
import base64
import hashlib
import struct
# 向客户端发送消息
def send_msg(conn,msg_bytes):
token=b"x81"
length=len(msg_bytes)
if length<126:
token+=struct.pack("B",length)
elif length<0xFFFF:
token+=struct.pack("!BH",126,length)
else:
token+=struct.pack("!BQ",127,length)
msg=token+msg_bytes
print(msg)
conn.send(msg)
return True
def get_websocket_message(str_header):
header,body=str_header.split(b'rnrn')
header_dict={}
headers=header.split(b'rn')
for str_spilt in headers:
str_hd=str_spilt.split(b':')
if len(str_hd)==2:
header_dict[str(str_hd[0],encoding='utf-8')]=str(str_hd[1],encoding='utf-8').strip()
magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
values=header_dict['Sec-WebSocket-Key']+magic_string
ac=base64.b64encode(hashlib.sha1(values.encode('utf-8')).digest())
request_tpl="HTTP/1.1 101 Switching Protocolsrn" 
"Upgrade: websocketrn" 
"Connection: Upgradern" 
"Sec-WebSocket-Accept: %srnrn" %(str(ac,encoding='utf-8'))
return request_tpl.encode('utf-8')
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.bind(('127.0.0.1',8096))
sock.listen(5)
# 等待用户连接
conn,addr=sock.accept()
# 握手消息
data=conn.recv(8096)
# 获取握手消息,magic_string,shal加密
# 发送给客户端
recv=get_websocket_message(data)
conn.send(recv)
# 建立成功后,接收客户端发过来的消息
info = conn.recv(1024)
# 解析客户端发过来的数据
while True:
# payload_len决定数据头和数据所占的位数
# payload_len等于126,要在往后移2字节,即16bit
# payload_len等于127,要在往后移8字节,即64bit
# mask解码
payload_len=info[1] & 127
if payload_len==126:
extend_payload_len=info[2:4]
mask=info[4:8]
decoded=info[8:]
elif payload_len==127:
extend_payload_len = info[2:10]
mask = info[10:14]
decoded = info[14:]
else:
extend_payload_len = None
mask = info[2:6]
decoded = info[6:]
bytes_list=bytearray()
for i in range(len(decoded)):
chunk=decoded[i] ^ mask[i % 4]
bytes_list.append(chunk)
body=str(bytes_list,encoding="utf-8")
print(body)
text=input(">>>")
send_msg(conn,bytes(text,encoding="utf-8"))
WebSocket.py

转载于:https://www.cnblogs.com/lujiacheng-Python/p/10293830.html

最后

以上就是自然冬瓜为你收集整理的基于socket实现websocket服务的全部内容,希望文章能够帮你解决基于socket实现websocket服务所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部