实验 10:Streams Echo 服务
前面的示例都用 sleep() 假装 I/O。这一节写一个真的 TCP 往返:客户端发一行文本,服务端回一行 echo: ...。
运行:
bash
python3 examples/asyncio_demos/10_stream_echo.py服务端
python
async def handle_echo(reader, writer):
data = await reader.readline()
writer.write(b"echo: " + data)
await writer.drain()
writer.close()
await writer.wait_closed()每个新连接进来时,asyncio 会安排 handle_echo() 执行。你不用自己写 accept 循环。
客户端
python
reader, writer = await asyncio.open_connection(host, port)
writer.write(b"hello\n")
await writer.drain()
data = await reader.readline()readline() 会等到读到换行符。示例里每条消息都带 \n,否则对方可能一直等。
drain 为什么不能省
writer.write() 通常只是把数据放进写缓冲。await writer.drain() 等的是:缓冲区压力太大时,先别继续写。
小 Demo 里省掉它也可能能跑。但在真实服务里,写得太快、对方读得太慢时,不等 drain() 会让内存风险变大。
关闭也要等待
python
writer.close()
await writer.wait_closed()close() 发起关闭,wait_closed() 等关闭完成。短脚本里少写这行可能看不出问题,长期运行的服务最好写完整。
小练习
- 把
readline()改成read(100),比较行为。 - 在
handle_echo里加await asyncio.sleep(0.1),观察三个 client 是否仍能并发。 - 去掉 client 发送消息时的
\n,程序会卡在服务端的reader.readline()。它一直在等换行符;验证完用Ctrl-C停掉。