简体   繁体   中英

python3.5 asyncio Protocol

I want to build a chat demo, but I can not receive the server-side things sent, in addition to the first time to start, anyone know why? code from 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()

result show: cant not show 'Data received: '#####' like 'def data_received(self, data)' is only used onece anyone have solution? [result][1] [1]: https://i.stack.imgur.com/IoqA9.png

You created so-called blocking function from EchoClientProtocol.data_received() . Every delivered message from server can be delivered into EchoClientProtocol.data_received() only when the event loop can process it but blocking function prevents it.

This code

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

get message from user and send it to the server, until this moment it's all fine. In the next step it starts another loop but the code never get into the event loop (so the incoming message can't be processed).

You can edit the client code like this:

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

The data_received in client is first called when you received Hello World! from server (it's the Hello World! sends from connection_made ). Now the processing is following:

  1. It prints received message (in the first call it's Hello World! )
  2. Get new message from user
  3. Send it to the server
  4. The function returns and the control is given to the event loop.
  5. The server received new message and send it back to client
  6. The event loop on client call data_received
  7. Go to the step 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM