背景
学习一下websocket的建立连接和发送的过程。 操作步骤如下:
- 建立一个ws server,监听本地的8000端口
- 建立一个ws client,连接server
- client 向 server发送消息
- wireshark抓包分析整体过程
步骤
前置准备:
- python
- wireshark
ws server
安装依赖
pip install websockets
server.py如下
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import asyncio
import subprocess
import websockets
# create handler for each connection
async def handler(websocket, path):
while 1:
data = await websocket.recv()
print(f"server get data: {data}")
# 在本地shell执行输入的命令,
reply = subprocess.getoutput(data)
# 返回数据
await websocket.send(str(reply))
# 监听localhost:8000端口
start_server = websockets.serve(handler, "localhost", 8000)
asyncio.get_event_loop().run_until_complete(start_server)
# 运行server
asyncio.get_event_loop().run_forever()
ws client
client.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import asyncio
import websockets
import time
async def test():
async with websockets.connect('ws://localhost:8000/') as websocket:
while 1:
msg = input("cmd to exec: ")
await websocket.send(msg)
# sleep2s后再返回
time.sleep(2)
response = await websocket.recv()
# 打印返回
print(response)
asyncio.get_event_loop().run_until_complete(test())
发送数据
测试如下,左边是server,右边是client
client发pwd,server端执行完成后,将stdout返回给了client。
抓包分析
下面根据抓包的No进行分析
- 41: TCP 第一次握手,client发起连接,
SYN=1请求 - 42: TCP 第二次捂手,server
SYN=1,ACK=1(client的包SYN+1) - 43: TCP 第三次握手,客户端包检查
SYN是否为第一次发送的序号+1,以及标志位ACK是否为1。若正确则再次发送确认包,ACK=1。 - 44: TCP Window Update, tcp窗口更新
- 45: 关键,这里有一个http升级websocket的过程
- 后面的忽略,最后超时server主动
RST结束了长连接