Python3 网络编程6:异步网络编程 (asyncio)
在高并发网络应用中,传统的 socket 和 socketserver 可能会遇到 阻塞 问题。Python 的 asyncio 提供了一种 异步 IO 机制,可以实现高效的网络编程。
6.1 asyncio 基础
asyncio 允许使用 async 和 await 关键字编写 非阻塞 代码。
6.1.1 创建异步任务
import asyncio
async def my_task():
print("任务开始...")
await asyncio.sleep(2) # 模拟 IO 操作
print("任务完成!")
asyncio.run(my_task())
6.1.2 并发执行多个任务
import asyncio
async def task(name, seconds):
print(f"{name} 开始...")
await asyncio.sleep(seconds)
print(f"{name} 完成!")
async def main():
await asyncio.gather(task("任务 1", 2), task("任务 2", 3), task("任务 3", 1))
asyncio.run(main())
6.2 异步 TCP 服务器
使用 asyncio 可以创建 异步 TCP 服务器,支持高并发连接。
6.2.1 异步 TCP 服务器
import asyncio
async def handle_client(reader, writer):
data = await reader.read(100) # 读取数据
message = data.decode()
addr = writer.get_extra_info("peername")
print(f"收到来自 {addr} 的数据: {message}")
writer.write(b"Hello from Async TCP Server")
await writer.drain() # 发送数据
writer.close()
async def main():
server = await asyncio.start_server(handle_client, "0.0.0.0", 8888)
print("异步 TCP 服务器运行在端口 8888...")
async with server:
await server.serve_forever()
asyncio.run(main())
6.2.2 异步 TCP 客户端
import asyncio
async def tcp_client():
reader, writer = await asyncio.open_connection("127.0.0.1", 8888)
writer.write(b"Hello Async Server")
await writer.drain()
response = await reader.read(100)
print(f"收到服务器响应: {response.decode()}")
writer.close()
await writer.wait_closed()
asyncio.run(tcp_client())
6.3 异步 UDP 服务器
6.3.1 异步 UDP 服务器
import asyncio
class MyUDPServerProtocol(asyncio.DatagramProtocol):
def datagram_received(self, data, addr):
print(f"收到来自 {addr} 的数据: {data.decode()}")
self.transport.sendto(b"Hello from Async UDP Server", addr)
async def main():
loop = asyncio.get_running_loop()
transport, protocol = await loop.create_datagram_endpoint(
lambda: MyUDPServerProtocol(), local_addr=("0.0.0.0", 9999)
)
print("异步 UDP 服务器运行在端口 9999...")
await asyncio.sleep(3600) # 运行 1 小时
asyncio.run(main())
6.3.2 异步 UDP 客户端
import asyncio
async def udp_client():
loop = asyncio.get_running_loop()
transport, protocol = await loop.create_datagram_endpoint(
lambda: asyncio.DatagramProtocol(), remote_addr=("127.0.0.1", 9999)
)
transport.sendto(b"Hello Async UDP Server")
await asyncio.sleep(1) # 等待服务器响应
asyncio.run(udp_client())
6.4 aiohttp:异步 HTTP 客户端与服务器
aiohttp 是一个 异步 HTTP 库,适用于爬虫、API 调用和 Web 服务器。
6.4.1 安装 aiohttp
pip install aiohttp
6.4.2 创建异步 HTTP 服务器
from aiohttp import web
async def handle(request):
return web.Response(text="Hello, Async HTTP Server!")
app = web.Application()
app.router.add_get("/", handle)
web.run_app(app, host="0.0.0.0", port=8080)
6.4.3 创建异步 HTTP 客户端
import aiohttp
import asyncio
async def fetch():
async with aiohttp.ClientSession() as session:
async with session.get("http://127.0.0.1:8080") as response:
print(await response.text())
asyncio.run(fetch())
下篇文章我们将介绍 WebSocket 编程,实现实时双向通信!