• Twisted网络框架


    1.异步编程模型
    2.反应堆模式
    3.Twisted框架的基本使用方法
    4.使用Twisted框架实现时间戳客户端和服务器

    一。目前常用的编程模型有3种:同步编程模型,线程编程模型和异步编程模型

    同步编程模型:所有的任务都在一个线程种完成,线程中的任务都是顺序执行的,也就是说,只有当执行完第一个任务,才会执行第二个任务。
    线程编程模型:要完成多个任务,可以将这些任务分解,然后启动多个线程,每个线程处理一部分任务,最后再将处理结果合并。这样做的好处是,当一个任务被阻塞后,并不影响其他任务的执行。多线程执行效率的高低在某种程度上取决于计算机是否有多颗CPU,以及每颗CPU有多少个核。
    异步编程模型:当一个任务被阻塞后,就会立刻执行另一个任务;在异步编程模型中,从一个任务切换到另一个任务,要么是这个任务被阻塞,要么是这个任务执行完毕。

    二。Reactor(反应堆)模式

    异步编程模型之所以能监视所有的任务的完成和阻塞情况,是因为通过循环用非阻塞模式执行完了所有的任务。这种用循环体来等待事件发生,然后处理发生事件的模型被设计成了一个模式:Reactor(反应堆)模式.

    三。Twisted框架的基本使用方法

    1.Twisted的Reactor模式必须通过run函数启动
    2.Reactor循环是在开始的进程中,也就是运行在主进程中
    3.一旦启动Reactor,就会一直运行下去。Reactor会在程序的控制之下
    4.Reactor循环并不会消耗任何CPU资源
    5.并不需要显示式创建Reactor循环,只要导入reactor模式就可以了。也就是说,Reactor是Singleton(单件)模式,即在一个程序中只能有一个Reactor
    Twisted可以使用不同的Reactor,但需要在导入twisted.internet.reactor之前安装它。
    在它之前引用,如:安装pollreactor,把他作为当前的reactor

    from twisted.internet import pollreactor
    # 安装pollreactor
    pollreactor.install()
    

    下面这段代码在reactor循环开始后向终端打印一条消息;hello函数是在reactor启动后被调用的,这就意味着Twisted调用了hello函数。通过调用reactor的callWhenRunning函数,让reactor启动回调callWhenRunning函数指定的回调函数

    def hello():
        print('Hello,How are you?')
    from twisted.internet import reactor
    
    # 执行回调函数
    reactor.callWhenRunning(hello)
    print('Starting the reactor.')
    reactor.run()
    

    函数回调需要了解以下几点
    1.reactor模式是单线程的
    2.向Twisted这种交互模型已经实现了reactor循环,这就意味着无须亲自去实现它
    3.仍然需要框架来调用自己的代码完成业务逻辑
    4.因为在单线程中运行,要想运行自己的代码,必须在reactor循环中调用他们
    5.reactor事先并不知道调用代码中的哪个函数

    四。使用Twisted框架实现时间戳客户端和服务器

    4.1利用Twisted框架实现一个时间戳客户端程序,在Concle中输入字符串,然后按回车键将字符串发送给时间戳服务端,最后时间戳服务端会返回服务器的事件和发送给服务器的字符串

    # 导入protocol模块和reactor模块
    from twisted.internet import protocol,reactor
    host = 'localhost'
    port = 9876
    # 定义回调类
    class MyProtocol(protocol.Protocol):
        # 从Console中采集要发送给服务器的数据,按回车键后,会见数据发送给服务器
        def sendData(self):
            data = input('>')
            if data:
                print('...正在发送 %s' % data)
                # 将数据发送给服务器
                self.transport.write(data.encode(encoding='utf_8'))
            else:
                # 发生异常后,关闭连接
                self.transport.loseConnection()
        # 发送数据
        def connectionMade(self):
            self.sendData()
        def dataReceived(self,data):
            # 输出接收到的数据
            print(data.decode('utf-8'))
            # 调用sendData函数,从Console采集要发送的数据
            self.sendData()
    # 工厂类
    class MyFactory(protocol.ClientFactory):
        protocol = MyProtocol
        # 下面这句话不知啥意思
        clientConnectionLost = clientConnectionFailed = lambda self,connector,reason:reactor.stop()
    # 连接host和port,以及MyFactory类的实例
    reactor.connectTCP(host,port,MyFactory())
    reactor.run()
    
    

    4.2利用Twisted框架实现一个时间戳服务端程序,启动后可以等待时间戳客户端程序连接

    from twisted.internet import protocol,reactor
    from time import ctime
    port = 9876
    class MyProtocol(protocol.Protocol):
        # 当客户端连接到服务端后,调用该方法
        def connectionMade(self):
            # 获取客户端的IP
            client = self.transport.getPeer().host
            print('客户端',client,'已经连接')
        def dataReceived(self,data): # 他是如何知晓这个data会传进来,又是如何传进来的
            # 接收到客户端发送过来的数据后,向客户端返回服务器的实际
            self.transport.write(ctime().encode(encoding='utf-8') + b' ' + data)
    # 创建Factory对象
    factory = protocol.Factory()
    factory.protocol = MyProtocol
    print('正在等待客户端连接')
    # 监听端口号,等待客户端的请求
    reactor.listenTCP(port,factory)
    reactor.run()
    

    来源于《python高校开发实战Django Tornado Flask Twisted》笔记

    努力拼搏吧,不要害怕,不要去规划,不要迷茫。但你一定要在路上一直的走下去,尽管可能停滞不前,但也要走。
  • 相关阅读:
    万维网
    MySQL客户端输出窗口显示中文乱码问题解决办法
    mysql数据库delete数据时不支持表别名
    Java 实现在固定区间内随机生成整数
    【面试】MySQL 中NULL和空值的区别?
    一个因MySQL大小写敏感导致的问题
    windows查看服务的状态
    不就是Select Count语句吗,竟然能被面试官虐的体无完肤!
    Java 代码的精优化
    java服务宕机原因查询
  • 原文地址:https://www.cnblogs.com/wkhzwmr/p/15229151.html
Copyright © 2020-2023  润新知