Skip to content

实验 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() 等关闭完成。短脚本里少写这行可能看不出问题,长期运行的服务最好写完整。

小练习

  1. readline() 改成 read(100),比较行为。
  2. handle_echo 里加 await asyncio.sleep(0.1),观察三个 client 是否仍能并发。
  3. 去掉 client 发送消息时的 \n,程序会卡在服务端的 reader.readline()。它一直在等换行符;验证完用 Ctrl-C 停掉。

面向学习目的的 Python asyncio 中文教程与 mini_asyncio 教学运行时。