日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Python3+WebSockets实现WebSocket通信

發(fā)布時(shí)間:2024/1/23 python 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python3+WebSockets实现WebSocket通信 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、說明

1.1 背景說明

前端時(shí)間同事說云平臺(tái)通信使用了一個(gè)websocket的東西,今天抽空來看一下具體是怎么個(gè)通信過程。

從形式上看,websocket是一個(gè)應(yīng)用層協(xié)議,socket是數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層的抽象;從應(yīng)用場合上看,websocket可以使用javascript實(shí)現(xiàn),而socket不能用javascript實(shí)現(xiàn);從實(shí)際效果上看,和一般的socket連接用起來沒什么區(qū)別。

我們知道http是短連接的,反復(fù)建立和銷毀連接比較耗費(fèi)資源,另外http協(xié)議經(jīng)常頭部內(nèi)容比主體內(nèi)容還長也比較浪費(fèi)資源;websocket可以認(rèn)為是一個(gè)內(nèi)容使用載荷固定格式的socket長連接。

websocket基本協(xié)議格式如下,更多說明見RFC 6455:

1.2 環(huán)境說明

當(dāng)前環(huán)境我使用Python3+WebSockets庫,WebSockets直接使用pip安裝即可:

pip install websockets

二、代碼實(shí)現(xiàn)

長連接是有狀態(tài)的,所以一般在且只在最開始進(jìn)行一次身份認(rèn)證,而后通信過程是不需要認(rèn)證信息。我們這里實(shí)現(xiàn)一個(gè)簡單的用戶名密碼認(rèn)證過程。長連接更多內(nèi)容可參考"連接與短連接的安全差異討論?”。

另外,注意把代碼中的ip改成自己的。

2.1 python服務(wù)端代碼

import asyncio import websockets# 檢測客戶端權(quán)限,用戶名密碼通過才能推出循環(huán) async def check_permit(websocket):while True:recv_str = await websocket.recv()cred_dict = recv_str.split(":")if cred_dict[0] == "admin" and cred_dict[1] == "123456":response_str = "congratulation, you have connect with server\r\nnow, you can do something else"await websocket.send(response_str)return Trueelse:response_str = "sorry, the username or password is wrong, please submit again"await websocket.send(response_str)# 接收客戶端消息并處理,這里只是簡單把客戶端發(fā)來的返回回去 async def recv_msg(websocket):while True:recv_text = await websocket.recv()response_text = f"your submit context:{recv_text}"await websocket.send(response_text)# 服務(wù)器端主邏輯 async def main_logic(websocket, path):await check_permit(websocket)await recv_msg(websocket)start_server = websockets.serve(main_logic, '10.10.6.91', 5678) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()

2.2 python版客戶端代碼

import asyncio import websockets# 向服務(wù)器端認(rèn)證,用戶名密碼通過才能退出循環(huán) async def auth_system(websocket):while True:cred_text = input("please enter your username and password:")await websocket.send(cred_text)response_str = await websocket.recv()if "congratulation' in response_str:return True# 向服務(wù)器端發(fā)送認(rèn)證后的消息 async def send_msg(websocket):while True:_text = input("please enter your context:")if _text == "exit":print(f'you have enter "exit", goodbye')await websocket.close(reason="user exit")return Falseawait websocket.send(_text)recv_text = await websocket.recv()print(f"{recv_text}")# 客戶端主邏輯 async def main_logic():async with websockets.connect('ws://10.10.6.91:5678') as websocket:await auth_system(websocket)await send_msg(websocket)asyncio.get_event_loop().run_until_complete(main_logic())

2.3 html版客戶端代碼

html版客戶端代碼,只能通過回調(diào)函數(shù)接收服務(wù)端返回的數(shù)據(jù),不能主動(dòng)接收,感覺怪怪的。

<!DOCTYPE HTML> <html><head><meta charset="utf-8"><title>websocket通信客戶端</title><script type="text/javascript">function WebSocketTest() {if ("WebSocket" in window) {// 打開一個(gè)web socketvar ws = new WebSocket("ws://10.10.6.91:5678");// 連接建立后的回調(diào)函數(shù)ws.onopen = function() {//Web Socket已連接上,使用send()方法發(fā)送數(shù)據(jù)ws.send("admin:123456");alert("正在發(fā)送:admin:123456");};//接收到服務(wù)器消息后的回調(diào)函數(shù)ws.onmessage = function (evt) {var received_msg = evt.data;if (received_msg.indexOf("sorry") == -1) {alert("收到消息:"+received_msg);}};// 連接關(guān)閉后的回調(diào)函數(shù)ws.onclose = function() {//關(guān)閉websocketalert("連接已關(guān)閉...");};} else {//瀏覽器不支持WebSocketalert("您的瀏覽器不支持 WebSocket!");}}</script></head><body onload="WebSocketTest()"></body> </html>

三、通信數(shù)據(jù)包截獲及通信過程分析

以下數(shù)據(jù)包基于上邊的python服務(wù)端和html版客戶端,再次強(qiáng)調(diào)注意把代碼中的ip改成自己電腦當(dāng)前的ip。

3.1 wireshark通信數(shù)據(jù)包截獲及通信過程分析

wireshark攔截?cái)?shù)據(jù)包后可使用過濾器表達(dá)式"websocket"進(jìn)行過濾:

我們追蹤數(shù)據(jù)流可以更清晰地看清websocket的通信過程,可以看到先是用http完成了建立連接,然后切換到websocket協(xié)議。

再看具體數(shù)據(jù)流也確實(shí)如此,先用兩個(gè)http包建立連接,而后是websocket通信.

3.2 burpsuite通信數(shù)據(jù)包截獲及通信過程分析

和正常配置代理即可,burpsuite能識(shí)別和攔截websocket數(shù)據(jù)包,如下圖:

不過和一般http請(qǐng)求有區(qū)別的是,websocket請(qǐng)求會(huì)被單獨(dú)匯總到“WebSocket history”選項(xiàng)卡,而不是和http請(qǐng)求混在"HTTP history"選項(xiàng)卡。

3.3 開發(fā)者工具通信數(shù)據(jù)包截獲及通信過程分析

FIreFox開發(fā)者工具只能看到簡歷websocket連接的兩個(gè)http數(shù)據(jù)包,沒看到怎么查看具體傳輸內(nèi)容,Chrome開發(fā)者工具Frames選項(xiàng)卡可以,如下:

參考:

https://websockets.readthedocs.io/en/stable/intro.html

https://www.runoob.com/html/html5-websocket.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的Python3+WebSockets实现WebSocket通信的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。