一、说明

1.1 背景说明

前段时间同事说云平台通信使用了个websocket的东西,今天抽空来看一下具体是怎么个通信过程。

从形式上看,websocket是一个应用层协议,socket是数据链路层、网络层、传输层的抽像;从应用场合上看,websocket可以使用javascript实现,而socket不能用javascript实现(真不能吗?我不太确定);从实际效果上看,和一般的socket连接用起来没什么区别。

我们知道http是短连接的,反复建立和销毁连接比较耗费资源,另外http协议经常头部内容比主体内容还长也比较浪费资源;websocket可以认为就是一个内容使用载荷固定格式的socket长连接。

websocket基本协议格式如下,更多说明见RFC 6455

1.2 环境说明

当前环境我使用Python3+WebSockets库,WebSockets直接使用pip安装即可:

pip install websockets

二、代码实现

长连接是有状态的,所以一般在且只在最开始进行一次身份认证,而后通信过程不需要认证信息。我们这里实现一个简单的用户名密码认证过程。长连接更多内容可参考“连接与短连接的安全差异讨论”。

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

2.1 python服务端代码

import asyncio
import websockets # 检测客户端权限,用户名密码通过才能退出循环
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] == "":
response_str = "congratulation, you have connect with server\r\nnow, you can do something else"
await websocket.send(response_str)
return True
else:
response_str = "sorry, the username or password is wrong, please submit again"
await websocket.send(response_str) # 接收客户端消息并处理,这里只是简单把客户端发来的返回回去
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) # 服务器端主逻辑
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 # 向服务器端认证,用户名密码通过才能退出循环
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 # 向服务器端发送认证后的消息
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 False
await 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版客户端代码,只能通过回调函数接收服务端返回的数据,不能主动接收,感觉怪怪的。

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>websocket通信客户端</title>
<script type="text/javascript">
function WebSocketTest()
{
if ("WebSocket" in window)
{
// 打开一个 web socket
var ws = new WebSocket("ws://10.10.6.91:5678"); // 连接建立后的回调函数
ws.onopen = function()
{
// Web Socket 已连接上,使用 send() 方法发送数据
ws.send("admin:123456");
alert("正在发送:admin:123456");
}; // 接收到服务器消息后的回调函数
ws.onmessage = function (evt)
{
var received_msg = evt.data;
if (received_msg.indexOf("sorry") == -1) {
alert("收到消息:"+received_msg);
} }; // 连接关闭后的回调函数
ws.onclose = function()
{
// 关闭 websocket
alert("连接已关闭...");
};
}
else
{
// 浏览器不支持 WebSocket
alert("您的浏览器不支持 WebSocket!");
}
} </script>
</head> <body onload="WebSocketTest()"> </body>
</html>

三、通信数据包截获及通信过程分析

以下数据包其于上边的python服务端和html版客户端,再次强调注意把代码中的ip改成自己电脑当前的ip。

3.1 wireshark通信数据包截获及通信过程分析

wireshark拦截数据包后可使用过滤器表达式“websocket”进行过滤:

我们追踪数据流可以更清晰地看清websocket的通信过程,可以看到先是用http完成了建立连接,然后切换到websocket协议。

再看具体数据流也确实如此,先用两个http包建立连接,而后是websocket通信(问题是不清楚websocket内容是怎么编码的,有些就显示不了原始内容)

3.2 burpsuite通信数据包截获及通信过程分析

和正常配置代理即可,burpsuite能识别和拦截websocket数据包,如下图:

不过和一般http请求有区别的是,websocket请求会被单独汇总到“WebSockets history”选项卡,而不是和http请求混在“HTTP history”选项卡。

3.3 开发者工具通信数据包截获及通信过程分析

Firefox开发者工具只能看到建立websocket连接的两个http数据包,没看到怎么查看具体传输内容,Chrome开发者工具Frames选项卡可以,如下:

参考:

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

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

Python3+WebSockets实现WebSocket通信的更多相关文章

  1. C#(SuperWebSocket)与websocket通信

    原文:C#(SuperWebSocket)与websocket通信 客户端代码 点击可以查看一些关于websocket的介绍 <!DOCTYPE html> <html> &l ...

  2. js判断是否安装某个android app,没有安装下载该应用(websocket通信,监听窗口失去焦点事件)

    现在经常有写场景需要提示用户下载app, 但是如果用户已经安装,我们希望是直接打开app. 实际上,js是没有判断app是否已经安装的方法的,我们只能曲线救国. 首先,我们需要有call起app的sc ...

  3. Springboot集成WebSocket通信全部代码,即扣即用。

    websocket通信主要来自两个类以及一个测试的html页面. MyHandler 和 WebSocketH5Config,下面全部代码 MyHandler类全部代码: package com.un ...

  4. 【Java Web开发学习】Spring MVC整合WebSocket通信

    Spring MVC整合WebSocket通信 目录 ========================================================================= ...

  5. websocket通信1009错误,

    问题说明: springboot继承 WebSocketConfigurer实现websocket通信服务,服务器端报错,"The decoded text message was too ...

  6. webSocket通信

    针对webSocket通信总结: 1.webSocket通信原理图: 2.webSocket通信实例 参考地址1:https://www.cnblogs.com/cjm123/p/9674506.ht ...

  7. 把酒言欢话聊天,基于Vue3.0+Tornado6.1+Redis发布订阅(pubsub)模式打造异步非阻塞(aioredis)实时(websocket)通信聊天系统

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_202 "表达欲"是人类成长史上的强大"源动力",恩格斯早就直截了当地指出,处在蒙昧时代即低 ...

  8. Python Web学习笔记之WebSocket 通信过程与实现

    一.什么是 WebSocket ? WebSocket 是一种标准协议,用于在客户端和服务端之间进行双向数据传输.但它跟 HTTP 没什么关系,它是基于 TCP 的一种独立实现. 以前客户端想知道服务 ...

  9. websocket通信 实现java模拟一个client与webclient通信

    发文原由: 熟悉socket通信的同学,对于socket模拟server与client,实现相互通信, 或者使用websocket与java模拟的websocket服务器通信(比如一个聊天室),对于这 ...

随机推荐

  1. springboot的pom.xml配置

    <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven ...

  2. 二、NodeJS入门——准备工作(2)——MongoDB安装以及客户端Robomongo安装和使用

    目录     1.介绍     2.下载地址     3.MongoDB安装过程     4.MongoDB的使用     5.MongoDB添加管理员账户     6.RoboMongo安装过程   ...

  3. javascript高级程序设计学习历程

    第三章 基本概念 3.1 语法 3.1.1 区分大小写 ECMAScript中的一切(变量,函数,操作符)都区分大小写的 3.1.2 标识符 标识符:变量,函数,属性的名字以及函数的参数. 标识符的命 ...

  4. Qt Creator清除最近工程历史信息

    Qt Creator清除最近工程历史信息 随着不断打开和关闭qt工程,欢迎->Projects->Recent projects下的历史工程信息越来越多,是该清理一下了,强迫症会追求干净一 ...

  5. Go语言学习——三分钟看透iota

    源起枚举 最近做需求时,有一个需要枚举的场景,大概有10+个枚举类型,不愿意像定义一个开关那样敷衍的写成 const ( SwitchOff = 0 SwitchOn = 1 ) 显得不够精致~ 于是 ...

  6. zookeeper中的QuorumPeerMain解析

    https://www.cnblogs.com/7758521gorden/p/8006983.html zookeeper中的QuorumPeerMain解析   在一个初级的hadoop与zook ...

  7. YUM方式安装MYSQL5.7

    首先mysql官网下载yum源https://dev.mysql.com/downloads/repo/yum/ 然后将下载好的rpm文件安装并校验 [root@elegant-snap-3 /sta ...

  8. java 使用网建SMS发送短信验证码

    首先, 注册并登录网建用户, 新注册用户将获得5条的测试短信 网建短信通地址: http://sms.webchinese.cn/default.shtml 注册账号在此就不多做赘述了, 直接上代码 ...

  9. Redash - 安装和初试

    前言 当业务成长到一定规模之后,会有许多想看各种不同类型报表的需求,如果单独做在后台,那么无疑会浪费前端和后端开发的时间.所以一直都有在寻找一款好用的BI工具.后面查了一下,市面上好用的一些非商业的B ...

  10. Mac下搭建Appnium+Python+Ios模拟器环境

    转载:https://www.jianshu.com/p/f7cf077d9444 https://blog.csdn.net/a158123/article/details/79684499 htt ...