导航:首页 > 编程语言 > pythonwebsocket库

pythonwebsocket库

发布时间:2023-09-04 06:12:45

❶ 如何用python获取websocket数据

这里,介绍如何使用 Python 与前端 js 进行通信。
websocket 使用 HTTP 协议完成握手之后,不通过 HTTP 直接进行 websocket 通信。
于是,使用 websocket 大致两个步骤:使用 HTTP 握手,通信。
js 处理 websocket 要使用 ws 模块; python 处理则使用 socket 模块建立 TCP 连接即可,比一般的 socket ,只多一个握手以及数据处理的步骤。
握手
过程

包格式
js 客户端先向服务器端 python 发送握手包,格式如下:
?

1
2
3
4
5
6
7
8

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

服务器回应包格式:
?

1
2
3
4
5

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

其中, Sec-WebSocket-Key 是随机的,服务器用这些数据构造一个 SHA-1 信息摘要。
方法为: key+migic , SHA-1 加密, base-64 加密,如下:

Python 中的处理代码
?

1
2

MAGIC_STRING='258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
res_key=base64.b64encode(hashlib.sha1(sec_key
+MAGIC_STRING).digest())

握手完整代码
js 端
js 中有处理 websocket 的类,初始化后自动发送握手包,如下:
var socket = new WebSocket('ws://localhost:3368');
Python 端
Python 用 socket 接受得到握手字符串,处理后发送
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

HOST='localhost'
PORT=3368
MAGIC_STRING='258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
HANDSHAKE_STRING="HTTP/1.1
101 Switching Protocols\r\n"
\
"Upgrade:websocket\r\n"\
"Connection:
Upgrade\r\n"
\
"Sec-WebSocket-Accept:
{1}\r\n"
\
"WebSocket-Location:ws://{2}/chat\r\n"

\
"WebSocket-Protocol:chat\r\n\r\n"

defhandshake(con):
#con为用socket,accept()得到的socket

headers={}
shake=con.recv(1024)

ifnot

len(shake):
returnFalse

header,
data =shake.split('\r\n\r\n',1)
forline
inheader.split('\r\n')[1:]:
key,
val =line.split(':
',1)
headers[key]=val

if'Sec-WebSocket-Key'

not
in
headers:
print('This
socket is not websocket, client close.')
con.close()
returnFalse

sec_key=headers['Sec-WebSocket-Key']
res_key=base64.b64encode(hashlib.sha1(sec_key
+MAGIC_STRING).digest())

str_handshake=HANDSHAKE_STRING.replace('{1}',
res_key).replace('{2}',
HOST +':'

+
str(PORT))
printstr_handshake
con.send(str_handshake)
returnTrue

通信
不同版本的浏览器定义的数据帧格式不同, Python 发送和接收时都要处理得到符合格式的数据包,才能通信。
Python 接收
Python 接收到浏览器发来的数据,要解析后才能得到其中的有用数据。
浏览器包格式

固定字节:
( 1000 0001 或是 1000 0002 )这里没用,忽略
包长度字节:
第一位肯定是 1 ,忽略。剩下 7 个位可以得到一个整数 (0 ~ 127) ,其中
( 1-125 )表此字节为长度字节,大小即为长度;
(126)表接下来的两个字节才是长度;
(127)表接下来的八个字节才是长度;
用这种变长的方式表示数据长度,节省数据位。
mark 掩码:
mark 掩码为包长之后的 4 个字节,之后的兄弟数据要与 mark 掩码做运算才能得到真实的数据。
兄弟数据:
得到真实数据的方法:将兄弟数据的每一位 x ,和掩码的第 i%4 位做 xor 运算,其中 i 是 x 在兄弟数据中的索引。
完整代码
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

defrecv_data(self,
num):
try:
all_data=self.con.recv(num)
ifnot

len(all_data):
returnFalse
except:
returnFalse
else:
code_len=ord(all_data[1])
& 127
ifcode_len
==126:
masks=all_data[4:8]
data=all_data[8:]
elifcode_len
==127:
masks=all_data[10:14]
data=all_data[14:]
else:
masks=all_data[2:6]
data=all_data[6:]
raw_str=""
i=0
ford
indata:
raw_str+=chr(ord(d)
^ ord(masks[i%4]))
i+=1
returnraw_str

js 端的 ws 对象,通过 ws.send(str) 即可发送
ws.send(str)
Python 发送
Python 要包数据发送,也需要处理,发送包格式如下

固定字节:固定的 1000 0001( ‘ \x81 ′ )
包长:根据发送数据长度是否超过 125 , 0xFFFF(65535) 来生成 1 个或 3 个或 9 个字节,来代表数据长度。
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

defsend_data(self,
data):
ifdata:
data=str(data)
else:
returnFalse
token="\x81"
length=len(data)
iflength
< 126:
token+=struct.pack("B",
length)
eliflength
<=0xFFFF:
token+=struct.pack("!BH",126,
length)
else:
token+=struct.pack("!BQ",127,
length)
#struct为Python中处理二进制数的模块,二进制流为C,或网络流的形式。
data='%s%s'

%
(token, data)
self.con.send(data)
returnTrue

js 端通过回调函数 ws.onmessage() 接受数据
?

1
2
3
4
5

ws.onmessage
= function(result,nTime){
alert("从服务端收到的数据:");
alert("最近一次发送数据到现在接收一共使用时间:"+
nTime);
console.log(result);
}

最终代码
Python服务端
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

#
_*_ coding:utf-8 _*_
__author__='Patrick'

importsocket
importthreading
importsys
importos
importMySQLdb
importbase64
importhashlib
importstruct

#
====== config ======
HOST='localhost'
PORT=3368
MAGIC_STRING='258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
HANDSHAKE_STRING="HTTP/1.1
101 Switching Protocols\r\n"
\
"Upgrade:websocket\r\n"\
"Connection:
Upgrade\r\n"
\
"Sec-WebSocket-Accept:
{1}\r\n"
\
"WebSocket-Location:ws://{2}/chat\r\n"

\
"WebSocket-Protocol:chat\r\n\r\n"

classTh(threading.Thread):
def__init__(self,
connection,):
threading.Thread.__init__(self)
self.con=connection

defrun(self):
whileTrue:
try:
pass
self.con.close()

defrecv_data(self,
num):
try:
all_data=self.con.recv(num)
ifnot

len(all_data):
returnFalse
except:
returnFalse
else:
code_len=ord(all_data[1])
& 127
ifcode_len
==126:
masks=all_data[4:8]
data=all_data[8:]
elifcode_len
==127:
masks=all_data[10:14]
data=all_data[14:]
else:
masks=all_data[2:6]
data=all_data[6:]
raw_str=""
i=0
ford
indata:
raw_str+=chr(ord(d)
^ ord(masks[i%4]))
i+=1
returnraw_str

#
send data
defsend_data(self,
data):
ifdata:
data=str(data)
else:
returnFalse
token="\x81"
length=len(data)
iflength
< 126:
token+=struct.pack("B",
length)
eliflength
<=0xFFFF:
token+=struct.pack("!BH",126,
length)
else:
token+=struct.pack("!BQ",127,
length)
#struct为Python中处理二进制数的模块,二进制流为C,或网络流的形式。
data='%s%s'

%
(token, data)
self.con.send(data)
returnTrue

#
handshake
defhandshake(con):
headers={}
shake=con.recv(1024)

ifnot

len(shake):
returnFalse

header,
data =shake.split('\r\n\r\n',1)
forline
inheader.split('\r\n')[1:]:
key,
val =line.split(':
',1)
headers[key]=val

if'Sec-WebSocket-Key'

not
in
headers:
print('This
socket is not websocket, client close.')
con.close()
returnFalse

sec_key=headers['Sec-WebSocket-Key']
res_key=base64.b64encode(hashlib.sha1(sec_key
+MAGIC_STRING).digest())

str_handshake=HANDSHAKE_STRING.replace('{1}',
res_key).replace('{2}',
HOST +':'

+
str(PORT))
printstr_handshake
con.send(str_handshake)
returnTrue

defnew_service():
"""start
a service socket and listen
when
coms a connection, start a new thread to handle it"""

sock=socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
try:
sock.bind(('localhost',3368))
sock.listen(1000)
#链接队列大小
print"bind
3368,ready to use"
except:
print("Server
is already running,quit")
sys.exit()

whileTrue:
connection,
address =sock.accept()
#返回元组(socket,add),accept调用时会进入waite状态
print"Got
connection from ",
address
ifhandshake(connection):
print"handshake
success"
try:
t=Th(connection,
layout)
t.start()
print'new
thread for client ...'
except:
print'start
new thread error'
connection.close()

if__name__
=='__main__':
new_service()

js客户 端
?

1
2
3
4
5
6
7
8

<script>
varsocket
= newWebSocket('ws://localhost:3368');
ws.onmessage
= function(result,nTime){
alert("从服务端收到的数据:");
alert("最近一次发送数据到现在接收一共使用时间:"+
nTime);
console.log(result);
}
</script>

❷ python怎么连接websocket

websocket是html5引入的一个新特性,传统的web应用是通过http协议来提供支持,如果要实时同步传输数据,需要轮询,效率低下

websocket是类似socket通信,web端连接服务器后,握手成功,一直保持连接,可以理解为长连接,这时服务器就可以主动给客户端发送数据,实现数据的自动更新。

使用websocket需要注意浏览器和当前的版本,不同的浏览器提供的支持不一样,因此设计服务器的时候,需要考虑。

❸ python怎么连接websocket

如果只是模拟js端发送接收的话,已经有了websocket server的话,只有client就好了

pip install websocket-client

websocket_client.py(客户端)
#-*-encoding:utf-8-*-

importsys
sys.path.append("..")
fromsocketimport*
importjson,time,threading
fromwebsocketimportcreate_connection
reload(sys)
sys.setdefaultencoding("utf8")

#config={
#'HOST':'127.0.0.1',
#'PORT':10010
#}
#pipinstallwebsocket-client

classClient():
def__init__(self):
#调用create_connection方法,建立一个websocket链接,链接是自己的链接
self.ws=create_connection("ws://127.0.0.1:10010/xxxx")
#建一个线程,监听服务器发送给客户端的数据
self.trecv=threading.Thread(target=self.recv)
self.trecv.start()


#发送方法,聊天输入语句时调用,此处默认为群聊ALL
defsend(self,content):
#这里的msg要根据实际需要自己写
msg={
"type":"POST",
"content":content
}
msg=json.mps(msg)
self.ws.send(msg)

#接收服务端发送给客户的数据,只要ws处于连接状态,则一直接收数据
defrecv(self):
try:
whileself.ws.connected:
result=self.ws.recv()
print"receivedmsg:"+str(result)
exceptException,e:
pass

if__name__=='__main__':

c=Client()
#建立链接后,就可以按照需要自己send了
c.send(content)

❹ 使用Python Websockets库建立WebSocket客户端链接

使用with语句进行connect连接后的上下文自动管理,当hello协程退出时,自动关闭该WebSocket连接。

不同于基本示例的是,connect函数中需要指定ssl参数做戚的内容

可以看到与基本示例不同的地方在纯森陵于:1.不再使用with进行自动的上下文管理;2.使用while语句进行长连接的处理,如果需要能够自己控制长连接的关闭,那么可以设置一个变量比如conn_flag,初始化其值为True,当收到退出连接的命令时,将conn_flag置为False,即可实现连接春运的可控退出。
Enjoy it!

阅读全文

与pythonwebsocket库相关的资料

热点内容
数控车床编程初学实例 浏览:944
cad中筛选命令是什么 浏览:800
数控铣床法兰克编程 浏览:330
怎么样分解压缩包图标 浏览:619
php两年工作经验简历 浏览:763
怎么提前解压房贷 浏览:698
反诈宣传app哪里可以拿到用户资料 浏览:855
华为交换机命令配置 浏览:11
电机pid算法实例c语言 浏览:972
安装ue5未找到金属编译器 浏览:963
l1压缩性骨折微创手术 浏览:615
看电脑配置命令 浏览:108
单片机调用db数值偏移量 浏览:446
奔驰smart车型压缩机功率 浏览:527
服务器预留地址获取 浏览:1004
云库文件夹怎么设置 浏览:295
文件夹目录制作自动跳转 浏览:454
在哪个音乐app能听exo的歌 浏览:850
pdf超级加密 浏览:50
苹果手机app安装包怎么解压并安装 浏览:907