为什么只有在python过程中断之后,为什么这个python 3 asyncio客户端仅发送字节



为什么我的客户端在代码线上出现:

response = yield from asyncio.wait_for(reader.read(), timeout=3.0)

而不是收回消息?

服务器部件仅注册它在客户times Out之后从该客户端收到一条消息,我实际上发布了ctrl + d以杀死Python解释器


客户端

@asyncio.coroutine
def test_connection(host, port):
    # Get the streams for the socket
    print('Starting client connection')
    reader, writer = yield from asyncio.open_connection(host, port)
    message = 'Test Message'.encode('ascii')
    # Start communication
    print('Sending message to {}:{} - {}'.format(host, port, message))
    writer.write(message)
    print('Waiting 3 sec for response...')
    response = yield from asyncio.wait_for(reader.read(), timeout=3.0)
    print('Got response: {}'.format(response.decode('ascii')))
    writer.close()

def run():
    loop = asyncio.get_event_loop()
    task = asyncio.async(test_connection())
    loop.run_until_complete(task)
    loop.close()

问题可能是您在服务器端(以及客户端)上调用reader.read(),该问题将阻止直到从服务器发送EOF。但是大概您没有这样做 - 您只是在发送一些字节并保持连接打开。

相反,您需要致电readline(),并确保将b'n'附加到MESS有效载荷上,致电read,以一定的尺寸限制您等待的字节数,或者在编写消息有效负载后致电writer.write_eof(),假设您don''T计划再使用writer。使用readline()write_eof可能是您最安全的选择。这是一个完整的示例,使用readline()

client.py

import asyncio
@asyncio.coroutine
def test_connection(host, port):
    # Get the streams for the socket
    print('Starting client connection')
    reader, writer = yield from asyncio.open_connection(host, port)
    message = 'Test Messagen'.encode('ascii')
    # Start communication
    print('Sending message to {}:{} - {}'.format(host, port, message))
    writer.write(message)
    print('Waiting 3 sec for response...')
    response = yield from asyncio.wait_for(reader.readline(), timeout=5.0)
    print('Got response: {}'.format(response.decode('ascii')))
    writer.close()

def run():
    loop = asyncio.get_event_loop()
    task = asyncio.async(test_connection('localhost', 5000))
    loop.run_until_complete(task)
    loop.close()
run()

server.py

import asyncio
@asyncio.coroutine
def got_connection(reader, writer):
    msg = yield from reader.readline()
    message = 'another Test Messagen'.encode('ascii')
    print('Sending message to {}:{} - {}'.format('localhost', 5000, message))
    writer.write(message)

def run():
    loop = asyncio.get_event_loop()
    server = loop.run_until_complete(asyncio.start_server(
                                        got_connection, 'localhost', 5000))
    loop.run_until_complete(server.wait_closed())
    loop.close()
run()

这是使用write_eof()的更改:

client.py

@asyncio.coroutine
def test_connection(host, port):
    # Get the streams for the socket
    print('Starting client connection')
    reader, writer = yield from asyncio.open_connection(host, port)
    message = 'Test Message'.encode('ascii')
    # Start communication
    print('Sending message to {}:{} - {}'.format(host, port, message))
    writer.write(message)
    writer.write_eof()
    print('Waiting 3 sec for response...')
    response = yield from asyncio.wait_for(reader.read(), timeout=5.0)
    print('Got response: {}'.format(response.decode('ascii')))
    writer.close()

server.py

@asyncio.coroutine
def got_connection(reader, writer):
    msg = yield from reader.read()
    message = 'another Test Message'.encode('ascii')
    print('Sending message to {}:{} - {}'.format('localhost', 5000, message))
    writer.write(message)
    writer.write_eof()