异步服务器客户端在没有输出的情况下提前终止

asyncio server client terminates early without output

我正在学习使用 async defawait 的 py3.5 语法中的 asyncio 库,并尝试编写一个简单的 server/client 架构。

由于某种原因,客户端从未收到消息并提前终止:

客户

IP = ''
PORT = 8880

import asyncio
import multiprocessing
import ssl

async def start_client(loop):
    reader, writer = await asyncio.open_connection(IP, PORT, loop=loop)
    writer.write("Gimme gimme gimme".encode())
    writer.close()
    data = await reader.read()
    print(data.decode())

loop = asyncio.get_event_loop()
loop.run_until_complete(start_client(loop))
loop.close()

服务器

IP = ''
PORT = 8880

import asyncio
import requests
import json

async def handle_echo(reader, writer):
    data = await reader.read()
    response = await whatsup()
    print(response)
    writer.write(response.encode())
    writer.write_eof()
    await writer.drain()
    writer.close()

async def whatsup():
    return "Hello there!"

loop = asyncio.get_event_loop()
server = asyncio.start_server(handle_echo,
            IP,
            PORT,
            loop=loop)
server = loop.run_until_complete(server)

try:
    loop.run_forever()
except:
    pass

server.close()
loop.run_until_complete(server.wait_closed())
loop.close()

我观察到服务器能够成功打印出 "Hello world!" 和 return,但据我所知,客户端总共读取了 0 个字节并退出.

我已经试过了

我试过:

while not reader.at_eof():
    data = await reader.read(100)
    print(data.decode())

但它评估 at_eof() 为真并提前退出。

好的,我找到了解决方案:

read() 将读取到 eof 标记。我们需要在两边都做 writer.write_eof() 才能读取 read()

解决方法代码如下:

async def handle_echo(reader, writer):
    data = await reader.read()
    response = await whatsup()
    print(response)
    writer.write(response.encode())
    writer.write_eof()
    await writer.drain()
    writer.close()

async def start_client(loop):
    reader, writer = await asyncio.open_connection(IP, PORT, loop=loop)
    writer.write("Gimme gimme gimme".encode())
    writer.write_eof() # crucial here
    writer.close()
    data = await reader.read()
    print(data.decode())