暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

补充-使用python 的【Socket】方式实践五个IO模型-异步IO(短链接)

小儿来一壶枸杞酒泡茶 2021-04-29
1386

关于异步IO,其实涉及的问题,很多这其中其实主要涉及的概念是协程,但是这些协程的引入过程中主要是付进程和线程的进一步的优化而来的。因为这里主要是补充异步IO的示例。关于协程的后续补上相关的梳理。

1 asyncio 简介

asyncio 是实现高兴并发的代表关键词,我们所了解到异步非阻塞的框架其实挺多:

早起的代表主要是:Twisted、Tornado和Gevent

后期的主要是:FastAPI,Quart,Sanic,Vibora,Tornado····等这些框架的出现主要是代表异步非阻塞的又有进一步发展了!

在异步非阻塞中,还引入事件循环与协程的引入,可以极大提高高负载下程序的I/O处理的性。

在不同的版本中关于异步的实现的方式是有所不同,在Python 3.5+发布之前,asyncio模块主要是是使用【生成器】的方式来模拟异步调用,从Python 3.5(包含3.5版本)之后开始引入了异步async及await关键字。async及await 极大的简化相关的异步回调处理的机制。

PS:需要注意点是:asyncio使用单线程、单个进程的方式运行的。

asyncio的核心是事件循环

首先我们的asyncio的异步任务的执行和任务执行完成的回调通知(网络IO等)都是通过事件循环完成的。

PS:python3.7 对于事件循环的机制的处理更简化了!不需要去理解透我们的事件循环(当然如果理解是最好滴)

2 asyncio中异步socket通信示例(官网示例)

官网示例地址:

PS:https://docs.python.org/3.7/library/asyncio-stream.html

下面是一个使用 asyncio streams 编写的 TCP echo 客户端示例:

PS: streams 是用于处理网络连接的高级 async/await-ready 原语。streams允许发送和接收数据,而不需要使用回调或低级协议和传输。

服务端示例:

此示例是:短链接的示例,就是客户端连接上发送和接收数据完成就关闭!

import asyncio

async def handle_echo(reader, writer):
    data = await reader.read(100)
    # 读取信息,然后进行解码
    message = data.decode()
    # 获取相关的信息
    addr = writer.get_extra_info('peername')
    print("接收来自客户端:", addr, '的数据是:',message)
    print("给客户端发送的数据是:",message)
    # 写入数据
    writer.write(data)
    await writer.drain()

    print(addr,"客户端进行了连接关闭")
    writer.close()

async def main():
    server = await asyncio.start_server(
        handle_echo, '0.0.0.0', 8000)

    # print(server.sockets,type(server.sockets))

    addr = server.sockets[0].getsockname()

    print(f'服务运行: {addr}')

    async with server:
        await server.serve_forever()

asyncio.run(main())



客户端示例:

#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   文件名称 :     serve3
   文件功能描述 :   功能描述
   创建人 :       小钟同学
   创建时间 :          2021/4/29
-------------------------------------------------
   修改描述-2021/4/29:         
-------------------------------------------------
"
""
import asyncio

async def tcp_echo_client(message):
    reader, writer = await asyncio.open_connection(
        '127.0.0.1', 8000)

    print(f'Send: {message!r}')
    writer.write(message.encode())

    data = await reader.read(100)
    print(f'Received: {data.decode()!r}')

    print('Close the connection')
    writer.close()
    await writer.wait_closed()

asyncio.run(tcp_echo_client('Hello World!'))

运行服务端后,再运行客户端则:看到客户端打印结果信息为:

Send: 'Hello World!'
Received: 'Hello World!'
Close the connection

服务端的引用结果信息为:

服务运行: ('0.0.0.0', 8000)
接收来自客户端: ('127.0.0.1', 64613) 的数据是:Hello World!
给客户端发送的数据是:Hello World!
('127.0.0.1', 64613) 客户端进行了连接关闭


PS:上面是一个短链接的示例,客户端发送和接收完成就就关闭!如果服务端不可关闭的,后续的客户端的发送也无法收到!

如果对异步底层的想了解更多的可以参考官网的文档。

参考资料:

官方文档:https://docs.python.org/zh-cn/3.7/library/asyncio-eventloop.html#asyncio-example-watch-fd

个人其他博客地址

简书:https://www.jianshu.com/u/d6960089b087

掘金:https://juejin.cn/user/2963939079225608

小钟同学 | 文 【原创】| QQ:308711822

  • 1:本文相关描述主要是个人的认知和见解,如有不当之处,还望各位大佬指正。
  • 2:关于文章内容,有部分内容参考自互联网,如有链接会声明标注;如没有及时标注备注的链接的,如有侵权请联系,我会立即删除处理哟。


文章转载自小儿来一壶枸杞酒泡茶,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论