Python asynchat模块-异步套接字处理-服务器程序示例

news2024/11/26 2:48:22

介绍

此模块在asyncore架构上建立,简化了异步客户端和服务器,并且使得处理元素为任意字符串结束或者为变长度的协议更加容易。asynchat定义了一个可以由使用者来子类化的抽象类async_chat,提供了collect_incoming_data()和found_terminator()等方法的实现。它使用与asyncore相同的异步循环,并且可以在通道映射中自由地混合asyncore.dispatcher和asynchat.aync_chat这两种类型地通道。一般来说asyncore.dispatcher服务器通道在接收到传入地连接请求时,会生成新地asynchat.async_chat通道对象。

class asynchat.async_chat

这个类是asyncore.dispatcher的抽象子类。对于实际使用的代码必须子类化async_chat,提供有意义的collect_incoming_data()和found_terminator()方法。asyncore.dispatcher的方法也可以被使用,但它们在消息/响应上下文中并不是全都有意义。

与asyncore.dispatcher类似,async_chat也定义了一组通过对select()调用之后的套接字进行分析所生成的事件。一旦启动轮询循环,async_chat对象的方法就会被事件处理框架调用而无需程序员方法做任何操作。

两个可被修改的类属性,用以提升性能,甚至也可能会节省内存。

1)ac_in_buffer_size:异步输入缓冲区大小(默认:4096)

2)ac_out_buffer_size:移除输出缓冲区大小。

与asyncore.dispatcher不同,async_chat允许你定义一个FIFO队列producer。其中的生产者只需要一个方法more(),该方法应当返回要在通道上传递的数据。生成者通过让其more()方法返回空字节串对象来表明其处于耗尽状态(它已不再包含数据)。此时,async_chat对象会将该生产者从队列中移除并开始使用下一个生产者,如果有下一个的话。当生产者队列为空时,handle_write()方法将不执行任何操作。你要使用通道对象的set_terminator()方法来描述如何识别来自远程端点的入站传输的结束或者重要的中断点。

要构建一个可用的async_chat子类,你的输入方法collect_incoming_data()和found_terminator()必须要处理通道异步接收的数据。

1)async_chat.close_when_done():将None推入生产者队列。当此生产者被弹出队列时,它将导致通道被关闭。

2)async_chat.collect_incoming_data(data):调用时附带data,其中包含任意数量的已接收数据。必须被重载的默认方法将引发一个NotImplementedError异常。

3)asyn_chat.discard_buffer():在紧急情况下,此方法将丢弃输入和/或输出缓冲区以及生产者队列中的任何数据。

4) asyn_chat.found_terminator():当输入数据流能匹配set_terminator()所设定的终结条件时被调用。必须被重载的默认方法将引发一个NotImplementedError异常。被缓存的输入数据应当可以通过实例属性来获取。

5)async_chat.get_terminator():返回通道的当前终止符。

6)async_chat.push(data):将数据推入通道的队列以确保其被传输。要让通道将数据写到网络中,只需要这样做就足够。

7)async_chat.push_with_producer(producer)

8)async_chat.set_terminator(term):设置可在通道上被识别的终结条件。term可以是三种类型值中的任何一种,对应于处理入站协议数据的三种不同方式。

术语        描述
string  当在输入流中发现这个字符串,将调用found_terminator()
integer在接收到指定数目字符时,将调用found_terminator()
None通道一直持续收集数据。

注意:在found_terminator()后,在终止符之后的任何数据将可用于由这个通道读取。

以下用一个示例展示使用 asynchat模块实现一个tcp服务:

服务器具有以下特性:

1) 识别一个以\r为终止符的字符串

2)它接收到字符串1返回One, 接收2返回Two,接收到3返回Three,接收到其它字符串时,返回Hello: + 接收到的字符串

3) 返回字符串以\r\n为终止符

源代码如下:

#!/usr/bin/env python3

import os

import sys
import asynchat
import asyncore
import socket

DEFAULT_PORT = 31337

class Echo:
    def parseCommand(self, num):
        if num == "1":
            return "One"
        elif num == "2":
            return "Two"
        elif num == "3":
            return "Three"
        else:
            return "Hello: " + num

class ConnectionDispatcher(asyncore.dispatcher):
        def __init__(self, port, echo):
                # 创建套接字,绑定IP地址和监听端口,开始监听
                asyncore.dispatcher.__init__(self)
                self.port = port
                self.device = echo
                self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
                self.set_reuse_addr()
                self.bind(("", port))
                self.listen(5)

        # 接受连接,调用服务处理方法
        def handle_accept(self):
                client_info = self.accept()
                print("client connected: ", client_info )
                ConnectionHandler(client_info[0], self.device)


class ConnectionHandler(asynchat.async_chat):
        # 设置输入终止符
        def __init__(self, sock, device):
                asynchat.async_chat.__init__(self, sock)
                self.set_terminator(b"\r")
                # 输出终止符格式
                self.outputTerminator = "\r\n"
                self.device = device
                self.buffer = ""
        # 收集数据
        def collect_incoming_data(self, data):
                self.buffer = self.buffer + data.decode()
        # 查找终止符,并把终止符之前的数据交给处理方法
        def found_terminator(self):
                data = self.buffer
                self.buffer = ""
                self.handleClientRequest(data)

        def handleClientRequest(self, request):
                request = request.strip()

                # 显示接收到的数据
                print(request)

                response = self.device.parseCommand(request)

                # 回应客户端
                if response != None:
                        self.sendClientResponse("{}".format(response))

                return

        def sendClientResponse(self, response=""):
                data = response + self.outputTerminator
                self.push(data.encode())


if __name__ == "__main__":
    if sys.version_info < (3,0,0) and sys.version_info < (3,12,0):
            sys.stderr.write("You need Python 3.0 or later (but less than 3.12) to run this script\n")
            input("Press enter to quit... ")
            sys.exit(1)

        # 尝试运行服务器
    try:
        echo = Echo()
        server = ConnectionDispatcher(DEFAULT_PORT, echo)
        asyncore.loop()
    except Exception as e:
        if isinstance(e, SystemExit):
            raise e
        else:
            print("Error: {}".format(e))
            sys.exit(1)

运行以上python代码。

以下是测试结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1020227.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构上机练习——单链表的基本操作、头文件、类定义、main函数、多种链表算法的实现,含注释

文章目录 单链表的基本操作实现1.头文件2.类定义和多种算法的实现2.1创建空表2.2头插法创建n个元素的线性链表2.3一个带头节点的链表存放一组整数&#xff0c;设计一个算法删除值等于x的所有节点。2.4计算线性表中值为偶数的节点个数2.5一个带头节点的单链表heada存放一组整数&…

科技云报道:云安全的新战场上,如何打破“云威胁”的阴霾?

科技云报道原创。 近年来&#xff0c;在云计算和网络安全产业的蓬勃发展下&#xff0c;我国云安全行业市场规模呈现高速增长态势&#xff0c;在网络安全市场总体规模中占比不断上升。 据统计&#xff0c;近5年我国云安全市场保持高速增长&#xff0c;2021年我国云安全市场规模…

VMware workstation 中centos7虚拟机在nat模式下怎么配置网卡,指定我想要的IP并且可以联网

1、首先打开我们的虚拟网络编辑器 2、查看我们的网关 3、查看IP池&#xff0c;根据需求自己设置 4、打开centos7虚拟机 编辑网卡配置 vim /etc/sysconfig/network-scripts/ifcfg-ens160####我的网卡是ens160TYPEEthernet PROXY_METHODnone BROWSER_ONLYno BOOTPROTOstatic …

全新交友平台,探索在线交流的乐趣!

大家好&#xff01;今天给大家介绍一款全新的交友平台&#xff0c;让您轻松享受在线交流的乐趣&#xff01;这个平台以其丰富多样的功能和互动体验而广受欢迎。无论您是想结识新朋友还是找到心仪的主播&#xff0c;这里都能满足您的需求。 首先&#xff0c;我们来看一下首页列表…

基于SpringBoot的超市管理系统

基于SpringBootVue的超市管理系统、超市进销存系统&#xff0c;前后端分离 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 【主要功能】 角色&#xff1a;管理员…

三、C#—变量,表达式,运算符(1)

&#x1f33b;&#x1f33b; 目录 一、变量1.1 变量1.2 使用变量的步骤1.3 变量的声明1.4 变量的命名规则1.5 变量的初始化1.6 变量初始化的三种方法1.7 变量的作用域1.8 变量使用实例1.9 变量常见错误 二、C#数据类型2.1 数据类型2.2 值类型2.2.1 值类型直接存储值2.2.2 简单类…

Vivado初体验LED工程

文章目录 前言一、PL 和 PS二、LED 硬件介绍三、创建 Vivado 工程四、创建 Verilog HDL 文件五、添加管脚约束六、添加时序约束七、生成 BIT 文件八、仿真测试九、下载测试 前言 本节我们要做的是熟练使用 Vivado 创建工程并实现对 LED 灯控制&#xff0c;每秒钟控制开发板上的…

微信小程序手写时间间隔组件,可设置间隔时间一分钟,半小时,一小时的间隔

纯手写时间间隔组件 需求&#xff1a;小程序中可以根据时间段进行选择开始时间和结束时间&#xff0c;如&#xff1a;当前时间是09&#xff1a;00&#xff0c; 则我可以从9点开始选择时间&#xff0c;每半个小时为间隔&#xff0c;那么下一个时间就算9&#xff1a;30&#xff…

vue基础知识十三:Vue中的$nextTick有什么作用?

一、NextTick是什么 官方对其的定义 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法&#xff0c;获取更新后的 DOM 什么意思呢&#xff1f; 我们可以理解成&#xff0c;Vue 在更新 DOM 时是异步执行的。当数据发生变化&#xff0c;Vue将开启一个异…

阿里测试岗:惨不忍睹的三面,幸好做足了准备,月薪17k,已拿offer....

我今年25岁&#xff0c;专业是电子信息工程本科&#xff0c;19年年末的时候去面试&#xff0c;统一投了测试的岗位&#xff0c;软件硬件都有&#xff0c;那时候面试的两家公司都是做培训的&#xff0c;当初没啥钱&#xff0c;他们以面试为谎言再推荐去培训这点让我特别难受。 …

开启编程之门

自我介绍 目前已经大二了&#xff0c;计算机专业在读&#xff0c;是一个热爱编程&#xff0c;做事踏实专注的人。转眼间一年已经过去了&#xff0c;也接触编程一年了&#xff0c;但开始并没有对所学所想进行很好的总结和输出&#xff0c;这一年也有了新的很多感悟与心得&#x…

JVM——5.类文件结构

这篇文章我们来讲一下jvm的类文件结构 目录 1.引言 2.类文件结构概论 3.魔数与class文件的版本 4.常量池 5.访问标志 6.类索引、父类索引与接口索引集合 7.字段表集合 8.方法表集合 9.属性表集合 9.1code属性 9.2 Exception属性 10小结 1.引言 代码编译的结果从本…

vue学习-02vue入门之组件

删除Vue-cli预设 在用户根目录下(C:\Users\你的用户名)这个地址里有一个.vuerc 文件,修改或删除配置 组件 Props(组件之间的数据传递) Prop 的大小写 (camelCase vs kebab-case)不敏感Prop 类型: String Number Boolean Array Object Date Function Symbol传递静态或动态 Pr…

「聊设计模式」之抽象工厂模式(Abstract Factory)

&#x1f3c6;本文收录于《聊设计模式》专栏&#xff0c;专门攻坚指数级提升&#xff0c;助你一臂之力&#xff0c;带你早日登顶&#x1f680;&#xff0c;欢迎持续关注&&收藏&&订阅&#xff01; 前言 在软件开发中&#xff0c;设计模式是一种被广泛使用的经验…

kudu 1.4.0 离线安装

1.准备rpm安装包 kudu-1.4.0: kudu的基础安装包 kudu-client0-1.4.0: kudu的c++客户端共享库 kudu-client-devel-1.4.0: kudu的c++客户端共享库sdk kudu-master-1.4.0: kudu master kudu-tserver-1.4.0: kudu tserver

任意输入一个整数m,若m不是素数,则对m进行质因数分解,并以质因数从小到大顺序排列的乘积形式输出

每个合数都可以写成几个质数&#xff08;也可称为素数&#xff09;相乘的形式 &#xff0c;这几个质数就都叫做这个合数的质因数。 #include <stdio.h> int isPrime(int num)// 判断一个数是否是素数 {if (num < 2) {return 0;}for (int i 2; i * i < num; i) {…

汽车电子 -- CAN总线波特率计算方法

上一篇文章介绍 PCAN View 安装与使用 的时候&#xff0c;留下了两个问题&#xff0c;CAN总线波特率该怎么计算&#xff1f; 下图里的这些 Prescaler、tseg1、tseg2、sync Jump Width是什么意思&#xff1f; CAN2.0协议中定义标称位速率为一理想的发送器在没有重新同步的情况…

2023年毫米波行业研究报告

第一章 行业概况 1.1 定义 毫米波是一种电磁波&#xff0c;其波长范围在1毫米至10毫米之间&#xff0c;频率介于30GHz至300GHz。与sub-6G (6GHz以下频段&#xff09;的5G系统相比&#xff0c;5G毫米波通信在带宽、时延和灵活弹性空口配置方面具有明显优势。这使其能够有效地满…

风车时间锁管理 - 构建IPA文件加锁+签名+管理一站式解决方案

时间锁管理&#xff1a;是一种用于控制对某些资源、功能或操作的访问权限的机制&#xff0c;它通过设定时间限制来限制对特定内容、系统或功能的访问或执行&#xff0c;以提高安全性和控制性&#xff0c;时间锁管理常见于以下场景&#xff1a; 1. 文件或文档的保密性&#xff…

STL list

文章目录 一、list 类的模拟实现 list 是一个带头双向循环链表&#xff0c;可以存储任意类型 模板参数 T 表示存储元素的类型&#xff0c;Alloc 是空间配置器&#xff0c;一般不用传 一、list 类的模拟实现 iterator 和 const_iterator 除了下述不同外&#xff0c;其他代码基…