python3.5 asyncio协议

时间:2017-07-28 17:43:08

标签: python-3.x tcp python-3.4 python-asyncio

我想建立一个聊天演示,但我无法收到服务器端发送的东西,除了第一次启动,有谁知道为什么? 代码来自https://docs.python.org/3.4/library/asyncio-protocol.html#tcp-echo-client-protocol

Server.py

import asyncio

class EchoServerClientProtocol(asyncio.Protocol):
    def connection_made(self, transport):
        peername = transport.get_extra_info('peername')
        print('Connection from {}'.format(peername))
        self.transport = transport

    def data_received(self, data):
        message = data.decode()
        print('Data received: {!r}'.format(message))
        print('Send: {!r}'.format(message))
        self.transport.write(data)


loop = asyncio.get_event_loop()
# Each client connection will create a new protocol instance
coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8888)
server = loop.run_until_complete(coro)

# Serve requests until Ctrl+C is pressed
print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()

Client.py

class EchoClientProtocol(asyncio.Protocol):
    def __init__(self, message, loop):
        self.message = message
        self.loop = loop
        self.transport = None

    def connection_made(self, transport):
        self.transport = transport

        transport.write(self.message.encode())
        print('Data sent: {!r}'.format(self.message))

        # while 1:
        #     message=input('please input the message:')
        #     transport.write(message.encode())
        #     print('Data sent: {!r}'.format(message))

    def data_received(self, data):
        # print('data_received')
        print('Data received: {!r}'.format(data.decode()))
        while 1:
            message = input('please input the message:')
            self.transport.write(message.encode())
            print('Data sent: {!r}'.format(message))

    def connection_lost(self, exc):
        print('The server closed the connection')
        print('Stop the event loop')
        self.loop.stop()

loop = asyncio.get_event_loop()
message = 'Hello World!'
coro = loop.create_connection(lambda: EchoClientProtocol(message, loop),
                              '127.0.0.1', 8888)
loop.run_until_complete(coro)
loop.run_forever()
loop.close()

结果显示: 无法显示'收到的数据:'#####' 像'def data_received(self,data)'只使用onece 谁有解决方案?     [结果] [1]       [1]:https://i.stack.imgur.com/IoqA9.png

1 个答案:

答案 0 :(得分:0)

您从EchoClientProtocol.data_received()创建了所谓的阻止功能。只有当事件循环可以处理它时,来自服务器的每个传递的消息都可以传递到EchoClientProtocol.data_received(),但是阻塞功能会阻止它。

此代码

while 1: # More Pythonic way is While True
    message = input('please input the message:')
    self.transport.write(message.encode())

从用户那里获取消息并将其发送到服务器,直到这一刻它一切正常。在下一步中,它会启动另一个循环,但代码永远不会进入事件循环(因此无法处理传入的消息)。

您可以像这样编辑客户端代码:

    def data_received(self, data):
        print('Data received: {!r}'.format(data.decode()))
        message = input('please input the message:')
        self.transport.write(message.encode())

当您从服务器收到data_received时,首先会调用客户端中的Hello World!Hello World!connection_made发送)。现在处理如下:

  1. 打印收到的消息(在第一次调用中为Hello World!
  2. 从用户那里获取新消息
  3. 将其发送至服务器
  4. 该函数返回并且控制权被赋予事件循环。
  5. 服务器收到新消息并将其发送回客户端
  6. 客户电话data_received
  7. 上的事件循环
  8. 转到第1步