如何与python TCP协议进行外部交互

问题描述

我有一个基于python文档的echo客户,如下所示:

import asyncio

class EchoClientProtocol(asyncio.Protocol):
    def __init__(self,message,on_con_lost):
        self.message = message
        self.on_con_lost = on_con_lost
        self.loop = asyncio.get_running_loop()

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

    def write_to_device(self):
        self.transport.write(self.message.encode())
    
    def data_received(self,data):
        print('Data received: {!r}'.format(data.decode()))
        self.loop.call_later(1.0,self.write_to_device)

    def connection_lost(self,exc):
        print('The server closed the connection')
        self.on_con_lost.set_result(True)


async def main(): 
    loop = asyncio.get_running_loop()
    on_con_lost = loop.create_future()
    message = 'Hello World!'

    transport,protocol = await loop.create_connection(
        lambda: EchoClientProtocol(message,on_con_lost),'127.0.0.1',8888)

    try:
        await on_con_lost
    finally:
        transport.close()

asyncio.run(main())

每次接收到来自服务器的消息时,都会在1秒后再次发送该消息。我的问题是:建立连接后,如何更改要发送的消息?

解决方法

好吧,只需按照建议的方式修改协议实例...这是一个简单的证明:

import asyncio


class EchoClientProtocol(asyncio.Protocol):
    def __init__(self,message,on_con_lost):
        self.message = message
        self.on_con_lost = on_con_lost
        self.loop = asyncio.get_running_loop()

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

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

    def data_received(self,data):
        print('Data received: {!r}'.format(data.decode()))
        self.loop.call_later(1,self.write_to_device)


    def connection_lost(self,exc):
        print('The server closed the connection')
        self.on_con_lost.set_result(True)


async def changeMessage(message,protocol):
    await asyncio.sleep(10)
    print('Changing message')
    protocol.message = message


async def main():
    # Get a reference to the event loop as we plan to use
    # low-level APIs.
    loop = asyncio.get_running_loop()

    on_con_lost = loop.create_future()
    message = 'Hello World!'

    transport,protocol = await loop.create_connection(
        lambda: EchoClientProtocol(message,on_con_lost),'127.0.0.1',65432)

    await changeMessage('Message is now changed',protocol)

    # Wait until the protocol signals that the connection
    # is lost and close the transport.
    try:
        await on_con_lost
    finally:
        transport.close()


asyncio.run(main())