python模块介绍-asyncore 异步socket处理器

该模块提供了异步socket服务客户端和服务器的基础架构。

只有两种方法让程序在单个处理器上的同时做超过一件的事情。 多线程编程是最简单,最普遍的方式,但还有另一种非常不同的技术,可以让你具有多线程几乎所有的优点,实际上并没有使用多线程。程序的瓶颈主要在于I/O时是比较可行的。如果你的程序的瓶颈在处理器,确实需要多线程,不过网络服务器的瓶颈大多在I/O。

如果您的操作系统支持I/O库的select()系统调用(一般都支持) ,那么你可以使用它同时处理多个通信信道,做其他的工作的同时让I/O在后台执行,这比多线程更容易理解。

asyncore和asynchat的基本思路是创建一个或多个网络通道,即asyncore.dispatcher和asynchat.async_chat的实例。然后添加到全局映射,如果你没有创建自己的映射,可以直接使用loop()函数。loop()激活所有通道服务,执行直到最后一个通道关闭。

接口文档

  • asyncore.loop([timeout[, use_poll[, map[, count]]]])

进入轮询循环直到所有打开的通道已被关闭或计数通过。所有的参数都是可选的。 count参数默认为None,只有当所有通道都被关闭时循环才会终止。 timeout参数设置为select()或poll()调用设置超时,以秒为单位,默认为30秒。use_poll参数,如果为true ,则表示 poll()优先于select(),默认值为False。map是包含监控的channel的字典。channel关闭时会从map中删除。不指定map时会使用全局map。Channel(asyncore.dispatcher , asynchat.async_chat和其子类的实例)可以自由地混合在map上)。

  • class asyncore.dispatcher: dispatcher底层socket的轻便包装。它有一些事件处理供异步循环调用。否则,它可以被视为一个正常的非阻塞socket对象。底层事件的触发或者连接状态改变通知异步循环发生了高层事件,高层事件有:

    • handle_connect():Implied by the first read or write event。

    • handle_close():Implied by a read event with no data available。

    • handle_accept():Implied by a read event on a listening socket。

  • asyncore.dispatcher的新方法:在异步处理,每个映射通道的readable()和writable()方法用于确定通道的socket是否应该被添加到select()或poll()通道的频道列表中以读写事件。因此通道事件比基本socket 事件要多。在子类中重写的方法如下:

    • handle_read():当异步循环检测到通道的read()将成功时调用。

    • handle_write():当异步循环检测到通道的write()将成功时调用。需要缓冲以提高性能。

      def handle_write(self):
          sent = self.send(self.buffer)
          self.buffer = self.buffer[sent:]
    • handle_expt():当有socket连接有带外数据【 out of band (OOB)】时调用。这几乎不会发生,因为OOB的支持很好且很少使用。

    • handle_connect():当活动socket实际创建连接时调用。可能发送“welcome” banner,或与远程端点启动协议协商。

    • handle_close():当关闭socket时调用。

    • handle_error():当异常引发又没有其他处理时调用。默认版本print压缩的traceback。

    • handle_accept():监听通道(被动开启) ,当本端通过connect()可以和远端建立连接时在监听通道(被动开启)上调用。

  • readable():每次异步循环时调用,以确定通道的socket是否应该被添加到产生读事件列表。默认的方法只返回True,表示在默认情况下,所有通道将拥有读取事件。

  • writable():每次异步循环时调用,以确定通道的socket是否应该被添加到产生写事件列表。默认的方法只返回True,表示在默认情况下,所有通道将拥有写事件。

  • 下面方法和socket相同,有些有所扩充:

    • create_socket(family, type):参见socket文档。

    • connect(address):参见socket文档。

    • send(data):发送数据到远端socket。

    • recv(buffer_size):从远端socket最多接收buffer_size字节的数据。空字符串意味着该信道已被远端关闭。

    • listen(backlog):监听的连接数,默认和最小值都为1,最大值根据系统确定,一般是5。

    • bind(address):绑定socket到address。socket必须未绑定。地址的格式取决于地址族 ,参见socket文档。调用set_reuse_addr()方法可以把socket设置为可重用的(参见设置SO_REUSEADDR选项)。

    • accept():接受连接。socket必须绑定到地址和监听连接。返回值可以是None 或一对(conn, address),其中conn是新的可用来在连接上发送和接收数据socket对象,address 是绑定到连接上远端套接字的地址。None意味着连接并没有发生,在这种情况下,服务器应该忽略并继续侦听其他连接。

    • close():关闭套接字。 Socket对象上的所有未来的操作将失败。远端将接收没有更多的数据(排队数据清空之后) 。socket也会被垃圾收集自动关闭。

  • asyncore.dispatcher_with_send:dispatcher的子类,增加了简单的缓冲输出,对于简单的客户端有用。详细资料参考:asynchat.async_chat。

  • class asyncore.file_dispatcher:封装了文件描述符或文件对象及映射参数(可选)供poll()和loop()函数使用的文件分发器。它提供了文件对象或其他具备fileno()方法的对象,调用fileno()并传递到file_wrapper构造函数。可用于UNIX。

  • class asyncore.file_wrapper:接收整数文件描述符并调用os.dup()复制句柄,这样原句柄可以关闭,而文件包装器不受影响。该类封装了大量方法以模拟socket给file_dispatcher类使用。可用于UNIX。

HTTP客户端实例

import asyncore, socketclass HTTPClient(asyncore.dispatcher):

    def __init__(self, host, path):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect( (host, 80) )
        self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path    def handle_connect(self):
        pass

    def handle_close(self):
        self.close()

    def handle_read(self):
        print self.recv(8192)

    def writable(self):
        return (len(self.buffer) > 0)

    def handle_write(self):
        sent = self.send(self.buffer)
        self.buffer = self.buffer[sent:]client = HTTPClient('192.168.4.13', '/env.htm')asyncore.loop()

上面的HTTPClient连接外面的服务器一般都会报不存在,连接本地的就好。

echo server

import asyncoreimport socketclass EchoHandler(asyncore.dispatcher_with_send):

    def handle_read(self):
        data = self.recv(8192)
        if data:
            self.send(data)class EchoServer(asyncore.dispatcher):

    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(5)

    def handle_accept(self):
        pair = self.accept()
        if pair is not None:
            sock, addr = pair            print 'Incoming connection from %s' % repr(addr)
            handler = EchoHandler(sock)server = EchoServer('localhost', 8080)asyncore.loop()

参考资料

本文地址


转载于:https://my.oschina.net/u/1433482/blog/190696

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值