python里使用协程来创建echo客户端

来源:互联网 发布:js href blank 编辑:程序博客网 时间:2024/06/08 17:46
在这个例子里使用asyncio.Protocol来创建一个echo客户端,先导入库asyncio和logging。
接着定义发送的消息MESSAGES。
创建连接服务器的地址SERVER_ADDRESS,接着创建EchoClient类,它是继承asyncio.Protocol。
在这个类的构造函数里,接收两个参数messages和future,
messages是指定要发送的消息数据,future是用来通知socket接收数据完成或者服务器关闭socket的事件通知,以便事件循环知道这个协程已经完成了,就可以退出整个程序。


connection_made函数是当socket连接到服务器时调用,它就立即发送数据给服务器,数据发送完成之后发送了eof标记。
服务器收到数据和标志都回复客户端,客户端data_received函数接收数据,eof_received函数接收结束标记。
connection_lost函数收到服务器断开连接。
这行代码:
client_completed = asyncio.Future()
创建一个协程完成的触发事件。


由于event_loop.create_connection函数只能接收一个参数,需要使用functools.partial来进行多个参数包装成一个参数。

后面通过事件循环来运行协程。

import asyncioimport functoolsimport loggingimport sysMESSAGES = [    b'This is the message. ',    b'It will be sent ',    b'in parts.',]SERVER_ADDRESS = ('localhost', 10000)class EchoClient(asyncio.Protocol):    def __init__(self, messages, future):        super().__init__()        self.messages = messages        self.log = logging.getLogger('EchoClient')        self.f = future    def connection_made(self, transport):        self.transport = transport        self.address = transport.get_extra_info('peername')        self.log.debug(            'connecting to {} port {}'.format(*self.address)        )        # This could be transport.writelines() except that        # would make it harder to show each part of the message        # being sent.        for msg in self.messages:            transport.write(msg)            self.log.debug('sending {!r}'.format(msg))        if transport.can_write_eof():            transport.write_eof()    def data_received(self, data):        self.log.debug('received {!r}'.format(data))    def eof_received(self):        self.log.debug('received EOF')        self.transport.close()        if not self.f.done():            self.f.set_result(True)    def connection_lost(self, exc):        self.log.debug('server closed connection')        self.transport.close()        if not self.f.done():            self.f.set_result(True)        super().connection_lost(exc)logging.basicConfig(    level=logging.DEBUG,    format='%(name)s: %(message)s',    stream=sys.stderr,)log = logging.getLogger('main')event_loop = asyncio.get_event_loop()client_completed = asyncio.Future()client_factory = functools.partial(    EchoClient,    messages=MESSAGES,    future=client_completed,)factory_coroutine = event_loop.create_connection(    client_factory,    *SERVER_ADDRESS,)log.debug('waiting for client to complete')try:    event_loop.run_until_complete(factory_coroutine)    event_loop.run_until_complete(client_completed)finally:    log.debug('closing event loop')    event_loop.close()

Python游戏开发入门

http://edu.csdn.net/course/detail/5690

你也能动手修改C编译器

http://edu.csdn.net/course/detail/5582

纸牌游戏开发

http://edu.csdn.net/course/detail/5538 

五子棋游戏开发

http://edu.csdn.net/course/detail/5487
RPG游戏从入门到精通
http://edu.csdn.net/course/detail/5246
WiX安装工具的使用
http://edu.csdn.net/course/detail/5207
俄罗斯方块游戏开发
http://edu.csdn.net/course/detail/5110
boost库入门基础
http://edu.csdn.net/course/detail/5029
Arduino入门基础
http://edu.csdn.net/course/detail/4931
Unity5.x游戏基础入门
http://edu.csdn.net/course/detail/4810
TensorFlow API攻略
http://edu.csdn.net/course/detail/4495
TensorFlow入门基本教程
http://edu.csdn.net/course/detail/4369
C++标准模板库从入门到精通 
http://edu.csdn.net/course/detail/3324
跟老菜鸟学C++
http://edu.csdn.net/course/detail/2901
跟老菜鸟学python
http://edu.csdn.net/course/detail/2592
在VC2015里学会使用tinyxml库
http://edu.csdn.net/course/detail/2590
在Windows下SVN的版本管理与实战 
http://edu.csdn.net/course/detail/2579
Visual Studio 2015开发C++程序的基本使用 
http://edu.csdn.net/course/detail/2570
在VC2015里使用protobuf协议
http://edu.csdn.net/course/detail/2582
在VC2015里学会使用MySQL数据库
http://edu.csdn.net/course/detail/2672