一文快速入门 HTTP 和 WebSocket 概念
一文快速入门 HTTP 和 WebSocket 概念
本文不转人工。
HTTP
http协议快速入门,给出一些构造例子:
HTTP(Hypertext Transfer Protocol)是用于客户端和服务器之间传输数据的协议。它基于请求和响应的模型,客户端(如浏览器)向服务器发出请求,服务器响应该请求。HTTP协议的基本操作包括请求请求行、请求头(headers)、请求体(body)等内容。
HTTP请求的基本结构:
请求行:包含请求方法(如 GET、POST)、请求的资源路径和协议版本。
请求头(Headers):提供关于客户端和请求的附加信息。
请求体(Body):包含请求的实际数据,通常在POST请求中出现。
HTTP响应的基本结构:
响应行:包含HTTP协议版本、状态码、状态描述。
响应头(Headers):提供关于响应的附加信息。
响应体(Body):包含实际的数据,通常是HTML、JSON或图片等。
1. HTTP请求示例
GET请求:
GET /index.html HTTP/1.1 Host: www.example.com User-Agent: Mozilla/5.0 Accept-Language: en-US,en;q=0.5 Connection: keep-alive
解释:
GET /index.html HTTP/1.1
:客户端请求/index.html
资源,使用的是HTTP/1.1协议。Host: www.example.com
:指定服务器的域名。User-Agent: Mozilla/5.0
:浏览器信息,告诉服务器请求是来自哪个浏览器。Accept-Language: en-US,en;q=0.5
:告诉服务器客户端能接受哪些语言。Connection: keep-alive
:表示连接在当前请求之后保持活动状态,以便在后续请求中重用。
POST请求:
POST /submit-form HTTP/1.1 Host: www.example.com Content-Type: application/x-www-form-urlencoded Content-Length: 27 name=JohnDoe&email=john@example.com
解释:
POST /submit-form HTTP/1.1
:客户端向/submit-form
发送数据。Content-Type: application/x-www-form-urlencoded
:表示发送的数据是表单数据(默认格式)。Content-Length: 27
:请求体的长度,指明了发送数据的字节数。请求体:
name=JohnDoe&email=john@example.com
,包含实际提交的数据。
2. HTTP响应示例
响应头:
HTTP/1.1 200 OK Date: Mon, 21 Sep 2025 12:00:00 GMT Server: Apache/2.4.41 (Ubuntu) Content-Type: text/html; charset=UTF-8 Content-Length: 1389 Connection: keep-alive
解释:
HTTP/1.1 200 OK
:服务器响应使用HTTP/1.1协议,状态码是200(表示请求成功)。Date: Mon, 21 Sep 2025 12:00:00 GMT
:响应生成的时间。Server: Apache/2.4.41 (Ubuntu)
:告诉客户端使用的服务器软件。Content-Type: text/html; charset=UTF-8
:返回的数据是HTML格式,字符集为UTF-8。Content-Length: 1389
:响应体的字节长度。
响应体:
html<html><head><title>Welcome</title></head><body><h1>Welcome to our website!</h1></body> </html>
解释:
返回的是HTML页面,显示一个简单的欢迎消息。
HTTP请求和响应中的Header是什么?
HTTP头(Headers)是请求和响应中用于传递附加信息的一部分。它们描述了请求和响应的附加数据、浏览器信息、编码格式、服务器信息等内容。Header在请求和响应中都扮演着重要角色。
常见的HTTP头部:
请求头:
User-Agent
:客户端的浏览器或应用信息。Accept
:客户端能够处理的响应内容类型,如Accept: text/html
。Content-Type
:请求体的类型,表明发送的数据格式。Authorization
:用于携带认证信息。
响应头:
Content-Type
:响应体的内容类型,如Content-Type: application/json
。Content-Length
:响应体的长度。Set-Cookie
:服务器设置的Cookie。Cache-Control
:缓存控制指令。
总结
请求行:如
GET /index.html HTTP/1.1
。请求头(Headers):携带关于请求的额外信息(如
User-Agent
,Accept
,Host
等)。请求体(Body):在POST请求中发送的实际数据。
响应行:如
HTTP/1.1 200 OK
。响应头(Headers):携带关于响应的额外信息(如
Content-Type
,Server
,Set-Cookie
等)。响应体(Body):服务器返回的数据。
这些基本构成了HTTP请求和响应的整个流程。希望这个入门能帮到你!
WebSocket
很多平台的开发者文档中提供websocket接口,请让我快速入门下:
我们来深入看看 WebSocket协议 的具体内容。WebSocket是一个独立于HTTP的协议,但它的握手是基于HTTP/1.1完成的。协议分为两个主要阶段:握手(Handshake) 和 数据传输(Framing)。
1. WebSocket握手(Handshake)
WebSocket连接是从客户端发起HTTP请求开始的,经过服务器响应升级协议后正式进入WebSocket通信。握手过程类似于HTTP请求升级:
1.1 客户端请求示例(HTTP Upgrade)
GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 Origin: http://example.com
字段解释:
GET /chat HTTP/1.1
:请求目标资源/chat
。Upgrade: websocket
:告诉服务器请求升级到WebSocket协议。Connection: Upgrade
:必须与Upgrade
一起使用,表示这是协议升级请求。Sec-WebSocket-Key
:客户端生成的随机Base64编码字符串,用于服务器生成响应Key。Sec-WebSocket-Version: 13
:WebSocket协议版本。Origin
:可选,表示请求来源,主要用于浏览器安全策略。
1.2 服务器响应示例
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
字段解释:
HTTP/1.1 101 Switching Protocols
:协议升级响应。Upgrade: websocket
:确认升级为WebSocket。Connection: Upgrade
:确认升级。Sec-WebSocket-Accept
服务器基于客户端的
Sec-WebSocket-Key
计算的响应,用于安全验证:
Sec-WebSocket-Accept = Base64( SHA1( Sec-WebSocket-Key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" ) )
握手完成后,HTTP连接升级为WebSocket连接,进入全双工通信阶段。
2. WebSocket数据传输(Frame帧)
WebSocket通信采用帧(Frame)来封装数据,每个消息被拆成若干帧传输,帧结构如下:
2.1 帧结构(基本)
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + | Masking-key, if MASK set | Payload Data | +-------------------------------+-------------------------------+
2.2 各字段说明
FIN (1 bit):是否为消息的最后一帧(1=是,0=不是)。
RSV1/2/3 (1 bit each):保留位,通常为0。
Opcode (4 bit)
:表示帧类型:
0x0
:延续帧0x1
:文本帧0x2
:二进制帧0x8
:关闭连接0x9
:Ping0xA
:Pong
Mask (1 bit):客户端发给服务器的帧必须为1(必须掩码),服务器发给客户端通常为0。
Payload length (7/7+16/7+64 bits):表示负载长度,可为7位、16位或64位,根据长度选择。
Masking-key (32 bits):客户端发送数据必须有,用于加密Payload。
Payload data:实际数据内容。
2.3 数据示例
假设客户端发送 "Hello" 给服务器:
先计算 Masked Payload(客户端必须对数据做掩码)。
构造帧,FIN=1, Opcode=0x1(文本)。
服务器收到后,解掩码获取原始文本数据。
3. 常用控制帧
Ping/Pong:心跳包,保持连接活跃。
Close (0x8):关闭连接,双方可以协商关闭状态码。
Text/Binary:传输文本或二进制数据。
4. Python中的底层协议封装
在Python中,websockets
库、websocket-client
等库已经封装了这些细节:
发送
await websocket.send("Hello")
→ 自动封装为帧、处理掩码。接收
message = await websocket.recv()
→ 自动解析帧、解掩码。
你通常不需要手动处理帧,但理解底层协议有助于:
调试网络问题。
对接非标准服务器。
理解心跳、二进制传输和消息拆分。
我可以给你画一张WebSocket握手 + 帧传输的流程图,让整个过程一眼就懂,非常直观。
gpt4o 画带中文汉字的图有问题,这里英文的效果还不错。
WebSocket 的 Python 使用
注意以下例子仅为简单示例,非工程性,使用 websockets 可以借助 高级 AI 大模型 辅助 进行 完善的、鲁棒的开发。
WebSocket 是一种在客户端与服务器之间进行全双工通信的协议,通常用于需要实时数据交换的应用,如在线聊天、游戏和金融数据流等。相比传统的HTTP协议,WebSocket能够在客户端和服务器之间建立持续的连接,使得数据可以实时双向传输。
1. WebSocket概述:
WebSocket协议:它是基于TCP的协议,能够提供全双工通信。
优点:与传统的HTTP请求/响应不同,WebSocket允许客户端和服务器之间的实时数据交换,不需要频繁建立连接,减少了延迟和带宽消耗。
2. 使用Python与WebSocket通信
Python有一个非常流行的库叫做websockets
,它可以非常方便地创建WebSocket客户端和服务器。
安装 websockets
库:
首先,你需要安装 websockets
库。可以使用 pip
来安装:
pip install websockets
3. 创建 WebSocket 客户端和服务器
WebSocket 服务器:
下面是一个简单的WebSocket服务器示例,使用websockets
库。
pythonimport asyncio import websockets # 处理每个连接的客户端 async def echo(websocket, path):print(f"Client connected: {path}")try:async for message in websocket:print(f"Received message: {message}")# 发送消息回客户端await websocket.send(f"Echo: {message}")except Exception as e:print(f"Error: {e}")finally:print("Client disconnected") # 启动WebSocket服务器 async def start_server():server = await websockets.serve(echo, "localhost", 8765) # 设置监听地址和端口print("Server started, waiting for clients...")await server.wait_closed() # 启动事件循环 asyncio.get_event_loop().run_until_complete(start_server())
解释:
websockets.serve()
:用于启动WebSocket服务器,监听localhost
上的8765端口。echo()
:每当客户端发送消息,服务器会回送相同的消息(回声功能)。使用
async for
来异步接收消息。await websocket.send()
:服务器发送消息给客户端。
WebSocket 客户端:
以下是一个与上面服务器通信的客户端示例:
pythonimport asyncio import websockets async def hello():uri = "ws://localhost:8765" # 连接的WebSocket服务器地址async with websockets.connect(uri) as websocket:message = "Hello, WebSocket!"await websocket.send(message) # 发送消息print(f"Sent message: {message}")response = await websocket.recv() # 接收服务器的消息print(f"Received message: {response}") # 启动客户端 asyncio.get_event_loop().run_until_complete(hello())
解释:
websockets.connect(uri)
:连接到服务器ws://localhost:8765
。await websocket.send(message)
:发送消息到服务器。response = await websocket.recv()
:接收服务器的回传消息。
4. 测试 WebSocket 服务
运行 WebSocket 服务器脚本。
在另一个终端运行 WebSocket 客户端脚本,客户端将向服务器发送“Hello, WebSocket!”消息,并接收回“Echo: Hello, WebSocket!”。
5. 处理异常和关闭连接
WebSocket连接在传输过程中可能会断开,以下是如何处理异常以及在连接关闭时进行清理的示例:
更新WebSocket服务器:
pythonasync def echo(websocket, path):print(f"Client connected: {path}")try:async for message in websocket:print(f"Received message: {message}")await websocket.send(f"Echo: {message}")except websockets.ConnectionClosedError:print("Connection closed")except Exception as e:print(f"Error: {e}")finally:print("Client disconnected")
更新WebSocket客户端:
pythonasync def hello():uri = "ws://localhost:8765"try:async with websockets.connect(uri) as websocket:message = "Hello, WebSocket!"await websocket.send(message)print(f"Sent message: {message}")response = await websocket.recv()print(f"Received message: {response}")except Exception as e:print(f"Error: {e}")
6. 实际应用:多客户端和广播
你可以通过使用一个管理所有连接的队列来实现广播消息给多个客户端。例如:
更新WebSocket服务器,实现广播:
pythonclients = set() async def echo(websocket, path):# 连接新的客户端clients.add(websocket)try:async for message in websocket:print(f"Received message: {message}")# 向所有客户端广播消息for client in clients:if client != websocket:await client.send(f"Broadcast: {message}")except Exception as e:print(f"Error: {e}")finally:clients.remove(websocket)print("Client disconnected")
7. WebSocket 连接关闭
WebSocket连接可以通过发送close()
来优雅地关闭。例如,客户端可以发送 await websocket.close()
来关闭连接。
更新客户端:
pythonawait websocket.close() # 关闭连接
总结:
使用
websockets
库可以非常方便地创建WebSocket服务器和客户端。WebSocket适用于实时通信需求,如在线聊天、金融数据、实时通知等。
在WebSocket的客户端和服务器中使用
asyncio
来处理并发任务,避免阻塞。
希望这些示例能帮助你快速入门WebSocket!