Python网络编程 课件 王菊雅 第4-11章 网络通信安全 - 网络自动化基础_第1页
Python网络编程 课件 王菊雅 第4-11章 网络通信安全 - 网络自动化基础_第2页
Python网络编程 课件 王菊雅 第4-11章 网络通信安全 - 网络自动化基础_第3页
Python网络编程 课件 王菊雅 第4-11章 网络通信安全 - 网络自动化基础_第4页
Python网络编程 课件 王菊雅 第4-11章 网络通信安全 - 网络自动化基础_第5页
已阅读5页,还剩172页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PYTHON网络编程第4章网络通信安全TLS/SSL协议与Python安全编程加密技术·证书管理·安全实践Contents目录01TLS/SSL基础深入理解加密与解密的核心原理,掌握对称加密与非对称加密的工作机制。详细解析TLS/SSL协议的工作流程,包括握手阶段与数据传输阶段。学习数字证书与信任链的验证机制,为构建安全通信打下坚实基础。02证书和密钥管理全面掌握主流证书格式(如PEM、DER、PKCS#12)及其应用场景。熟练运用OpenSSL、Keytool等工具进行证书操作。深入理解密钥的全生命周期管理策略,包括生成、存储、分发、轮换与销毁的最佳实践。03加密算法与安全最佳实践系统对比AES、RSA、ECC等主流加密算法的性能与安全性。深入探讨哈希函数与数字签名技术在保障数据完整性方面的应用。学习如何安全配置系统,识别并规避常见安全漏洞,构建纵深防御体系。04Python中的TLS/SSL应用熟练使用Pythonssl模块创建安全的客户端与服务器套接字。掌握SSL上下文的配置与证书验证流程。学习如何通过requests库与HTTPS服务进行安全交互,实现数据的加密传输与身份认证。CHAPTER014.1TLS/SSL基础加密解密基础与协议概述加密技术握手协议数字证书4.1.1加密和解密基础加密技术基础对称加密定义:使用相同密钥进行加密和解密特点:速度快,适合大数据量加密挑战:密钥分发和管理困难算法:AESDES3DES非对称加密定义:使用密钥对(公钥加密,私钥解密)特点:密钥分发更容易,公钥可公开挑战:加密解密速度较慢算法:RSAECCDiffie-Hellman数字签名与数字证书数字签名使用私钥签名,公钥验证,确保数据完整性和身份验证数字证书由CA签发,验证公钥所有权,建立信任机制TLS/SSL加密策略1握手阶段客户端与服务器建立连接初期,利用非对称加密技术安全地交换并协商出后续通信所需的对称密钥,确保密钥传输的机密性。2数据传输阶段握手完成后,双方使用已协商的高效对称密钥对应用数据进行加密和解密,在保证高强度安全的同时,大幅提升数据传输的效率。兼顾安全性与性能4.1.2TLS/SSL协议概述TLS/SSL协议工作原理加密保护数据传输隐私,防止第三方窃听敏感信息。身份验证通过数字证书验证通信双方身份,确保连接可信。数据完整性利用消息摘要和签名技术,确保数据在传输中不被篡改。TLS/SSL握手过程(图4-1)双方生成会话密钥,交换Finished消息加密套件组成密钥交换:RSA,DH,ECDH加密算法:AES,3DES,ChaCha20消息认证:HMAC-SHA256,HMAC-SHA1TLS版本演进SSL2.0/3.0→已废弃TLS1.0/1.1→逐步淘汰TLS1.2/1.3→推荐使用4.1.3数字证书和信任链数字证书与信任链数字证书结构(图4-2)证书版本:X.509版本号序列号:证书唯一标识签名算法:RSA/DSA/ECDSA颁发者:CA名称有效期:起止日期主体名称:实体域名/组织公钥信息:公钥及参数数字签名:CA私钥签名信任链验证过程(图4-3)证书颁发机构(CA)职责:签发、管理和撤销数字证书信任基础:根CA证书预装在操作系统和浏览器中安全要求:遵循严格的安全标准和操作规程自签名证书特点:由持有者自行创建签名,无外部CA认证信任度:通常不被外部实体信任应用场景:测试环境、内部网络Python证书验证示例import

sslcontext

=

ssl.create_default_context()context.load_verify_locations('ca.pem')context.load_cert_chain('cert.pem','key.pem')CHAPTER024.2证书和密钥管理证书格式、工具与密钥生命周期证书格式管理工具密钥管理4.2.1-4.2.2证书颁发机构与证书格式证书格式与管理工具证书格式对比(表4-1)格式特点扩展名PEMBase64编码,带边界标记.pem.crt.keyDER二进制形式,无额外编码.der.cerPKCS#12含证书和私钥,密码保护.p12.pfxP7B含证书链,不含私钥.p7b.p7cPEM应用Web服务器、邮件服务器DER应用Java平台、Windows系统CA层级结构(图4-4)证书工具(表4-2)OpenSSL强大的开源工具,用于SSL/TLS任务openssl

genpkey

-algorithm

RSA

-out

key.pemKeytoolJava密钥库管理工具keytool

-list

-keystore

keystore.jksCertbot自动化获取Let'sEncrypt证书certbot

certonly

--webroot

-w

/var/www/html

-d

管理挑战与最佳实践挑战安全存储密钥周期撤销机制最佳实践强密码+MFA定期更新自动化管理4.2.3密钥生成和管理密钥生成与管理策略密钥生命周期1密钥生成使用CSPRNG生成随机密钥。对称密钥可用os.urandom(32)生成256位密钥;非对称密钥可用RSA.generate_private_key生成2048位密钥对。2密钥存储私钥必须安全存储。推荐使用硬件安全模块(HSM)或加密密钥库(Keystore),避免明文存储在配置文件或代码中。3密钥分发对称密钥通过Diffie-Hellman等密钥交换协议安全传输;非对称密钥的公钥可通过数字证书公开分发,确保证书由可信CA签名。4密钥使用严格遵循密钥用途限制,避免密钥滥用。定期轮换密钥以降低泄露风险,确保加密系统的前向安全性。5密钥撤销与更新密钥泄露时立即撤销并通过CRL或OCSP通知。定期更新密钥,制定完善的备份与恢复计划。Python密钥生成示例对称密钥生成importos#生成256位随机密钥symmetric_key=os.urandom(32)非对称密钥生成fromcryptography.hazmat.primitives.asymmetricimportrsaprivate_key=rsa.generate_private_key(public_exponent=65537,key_size=2048)public_key=private_key.public_key()密钥管理最佳实践最小权限原则:仅授权必要人员访问密钥,实施严格的身份验证与细粒度的访问控制策略。定期审计:周期性审查密钥全生命周期日志,利用自动化工具监控异常访问行为。备份与恢复:制定可靠的密钥备份方案,确保在灾难或误删时能够快速恢复业务。完整生命周期:建立覆盖生成、分发、使用、轮换到销毁的端到端密钥管理策略。CHAPTER034.3加密算法与安全最佳实践算法对比、哈希函数与数字签名算法对比哈希函数安全配置4.3.1-4.3.2加密算法与数字签名加密算法对比与数字签名加密算法性能对比(表4-3)推荐:大数据量用AES,密钥交换用RSA/ECC,禁用DES/MD5哈希函数特点确定性:相同输入产生相同输出快速计算:任意长度数据快速计算抗碰撞性:不同输入难产生相同输出雪崩效应:微小变化导致显著差异SHA-256BLAKE2MD5数字签名工作原理(图4-5)数字签名特点身份验证:证明消息由持有私钥的实体发送不可否认性:发送方无法否认签署过的文档数据完整性:验证数据自签名以来未被篡改常用签名算法RSA签名ECDSAEdDSA4.3.3&4.4Python安全应用安全配置与PythonTLS/SSL应用安全配置最佳实践使用最新软件版本及时更新操作系统、应用和安全补丁最小化暴露面关闭不必要的服务和端口,使用防火墙加强认证机制强密码策略+多因素认证(MFA)配置安全协议优先TLS1.3,禁用SSLv3、RC4、MD5弱点避免措施•定期安全审计•漏洞扫描修复•安全编码培训•备份恢复计划PythonSSL客户端示例importsocket,ssl#创建SSL上下文ctx=ssl.create_default_context()#包装套接字sock=socket.socket()ssl_sock=ctx.wrap_socket(sock,server_hostname='')#连接并通信ssl_sock.connect(('',443))ssl_sock.send(b"GET/HTTP/1.1\r\nHost:...")data=ssl_sock.recv(4096)PythonSSL服务器示例importsocket,ssl#创建上下文并加载证书ctx=ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)ctx.load_cert_chain('cert.pem','key.pem')#包装并绑定sock=socket.socket()sock.bind(('localhost',443))sock.listen(5)#接受连接conn,addr=sock.accept()ssl_conn=ctx.wrap_socket(conn,server_side=True)提示:使用requests库可简化HTTPS请求,自动处理TLS/SSL握手本章小结网络通信安全核心要点TLS/SSL协议理解握手过程、加密套件和版本演进,掌握安全通信的基础加密技术掌握对称/非对称加密、哈希函数和数字签名的原理与应用证书管理理解数字证书、信任链和密钥生命周期管理的重要性TLS/SSL协议是保障网络通信安全的核心技术。通过掌握加密原理、证书管理和Python实现,开发者能够有效保护数据传输安全,防范安全威胁安全通信Python实现持续学习数据序列化与压缩DataSerializationandCompression计算机网络编程核心概念第5章本章概览ChapterOverview01字符串和字节数据StringandByteDataPython中的文本与二进制数据处理02数据封装和帧结构DataEncapsulation网络数据传输的基本单位03序列化格式SerializationFormatsJSON、XML、Protobuf的应用与对比04数据压缩技术DataCompression提升网络传输效率的关键技术05错误处理和异常ErrorHandlingandExceptions|构建健壮的网络应用01字符串和字节数据StringandByteDataPython中的文本与二进制数据处理5.1.1Python中的字符串和字节类型StringandByteTypesinPython字符串String定义:Unicode字符序列,用于表示文本数据特性:不可变(Immutable),一旦创建内容不能改变定义方式:单引号、双引号或三引号操作:支持拼接、分割、格式化等text="Hello,World!"字节Byte定义:不可变的字节序列,用于表示二进制数据表示:字面量通过前缀b表示,如b'hello'元素:0~255之间的整数,而非字符操作:支持大多数字符串类似操作data=b'hello'字符串与字节类型的转换字符串→字节encode()字节→字符串decode()网络编程要点:网络协议通常基于二进制数据,因此需要将字符串转换为字节类型进行传输。接收到的二进制数据也需解码回字符串处理。务必正确使用编码和解码,否则可能导致乱码。5.1.2编码转换和兼容性EncodingConversionandCompatibility1确定编码识别数据当前编码格式UTF-8ISO-8859-1GBK2解码将字节数据解码成Unicode字符串decode('原始编码')3重新编码编码成目标格式的字节数据encode('目标编码')编码兼容性问题数据传输:发送方和接收方编码不一致导致乱码系统间交互:不同操作系统默认编码设置不同国际化:全球化应用需支持多语言和字符集处理编码兼容性措施使用通用编码:尽可能使用UTF-8明确指定编码:HTTP头部指定charset错误处理:使用errors='ignore'或'replace'编码检测:使用chardet等第三方库编码转换示例代码original_data=b'TextwithISO-8859-1'unicode_text=original_data.decode('iso-8859-1')utf8_data=unicode_text.encode('utf-8')5.1.3字节序和网络字节顺序ByteOrderandNetworkByteOrder大端字节序Big-Endian最高字节(最重要的部分)存储在最低的内存地址,其余字节按照重要性递减的顺序存储。示例:32位整数0x1234567812345678↑低地址高地址→小端字节序Little-Endian最低字节(最不重要的部分)存储在最低的内存地址,其余字节按照重要性递增的顺序存储。示例:32位整数0x1234567878563412↑低地址高地址→网络字节顺序定义网络协议中保证数据一致性的约定,用于多字节数值传输的字节序标准互联网协议(TCP/IP)使用大端字节序作为网络字节顺序重要性确保不同系统间数据正确传递和解析,避免通信失败Python字节序转换函数(socket模块)htons(x)16位:主机→网络ntohs(x)16位:网络→主机htonl(x)32位:主机→网络ntohl(x)32位:网络→主机02数据封装和帧结构DataEncapsulationandFrame网络数据传输的基本单位5.2.1数据帧的概念和结构FrameConceptandStructure数据帧的三个主要部分帧头FrameHeader包含用于网络通信的控制信息,如源地址、目的地址、类型、长度等。可能还包括用于错误检测和纠正的信息,如校验和或序列号。有效载荷Payload帧中实际传输的数据部分。可以包含来自上层协议的数据包,如IP数据包或TCP/UDP段。帧尾FrameTrailer通常包含一个或多个校验字段,用于确保帧在传输过程中未被损坏。常见的校验方法包括循环冗余校验(CRC)。以太网帧结构示例目的MAC地址6字节源MAC地址6字节以太网类型2字节数据46~1500字节CRC校验4字节帧的处理流程帧到达目的地后,数据链路层检查帧尾校验字段验证数据完整性校验成功:帧头和帧尾被移除,有效载荷传递到上层协议校验失败:帧被丢弃,可能触发重传机制5.2.2封装和解封装数据EncapsulationandDecapsulation数据封装过程1数据准备应用层数据准备发送,如用户输入、文件内容等2添加协议头部每层添加对应头部信息(源/目的地址、端口号、校验和等)3封装成帧数据链路层封装成帧(帧头+有效载荷+帧尾)4发送通过物理层发送,如以太网、Wi-Fi等数据解封装过程1接收帧数据链路层接收从物理媒介传来的帧2验证和去除帧尾检查CRC等校验字段,失败则丢弃帧3去除协议头部逐层向上传递,每层去除对应头部信息4数据处理应用层接收原始数据,进行进一步处理数据完整性校验和等机制确保数据完整协议层次体现网络协议分层结构数据隔离每层只处理对应层次信息挑战与权衡:封装和解封装需要额外计算,可能影响性能;不同协议有不同封装要求,增加实现复杂性;需确保跨环境兼容性。5.2.2封装和解封装数据EncapsulationandDecapsulation数据封装过程1数据准备应用层数据准备发送,如用户输入、文件内容等2添加协议头部每层添加对应头部信息(源/目的地址、端口号、校验和等)3封装成帧数据链路层封装成帧(帧头+有效载荷+帧尾)4发送通过物理层发送,如以太网、Wi-Fi等5.2.2封装和解封装数据EncapsulationandDecapsulation数据解封装过程1接收帧数据链路层接收从物理媒介传来的帧2验证和去除帧尾检查CRC等校验字段,失败则丢弃帧3去除协议头部逐层向上传递,每层去除对应头部信息4数据处理应用层接收原始数据,进行进一步处理数据完整性校验和等机制确保数据完整协议层次体现网络协议分层结构数据隔离每层只处理对应层次信息挑战与权衡:封装和解封装需要额外计算,可能影响性能;不同协议有不同封装要求,增加实现复杂性;需确保跨环境兼容性。5.2.3帧同步和错误检测FrameSynchronizationandErrorDetection帧同步在数据流中识别帧边界的过程,每个帧的开始和结束都有特定的标识符(特殊比特模式)。帧定界符用于标识帧开始和结束的特殊序列,如以太网帧的前导序列和帧结束序列比特填充防止数据中出现与帧定界符相同的比特模式,发送方插入额外比特,接收方移除错误检测用于发现数据在传输过程中是否出现错误的机制。常见方法包括:奇偶校验添加额外比特使数据中1的数量为奇数或偶数,检测单比特错误循环冗余校验CRC使用特定多项式函数计算CRC值并添加到帧尾,重新计算并与接收到的CRC比较校验和计算数据总和作为校验和,接收方计算校验和验证数据完整性错误纠正机制前向纠错FEC允许接收方不仅检测错误,还能在一定程度上纠正错误,无需重新传输数据提高网络可靠性即使在不完美的传输媒介上也能有效工作性能优化减少需要重传的数据量,提高整体性能实现考虑:选择错误检测方法时需权衡效率与性能(CRC比奇偶校验更可靠但计算更复杂);应考虑网络特定条件(错误率、传输速率);遵循行业标准确保兼容性。03序列化格式SerializationFormatsJSON、XML、Protobuf的应用与对比5.3.1JSON的使用和特点JSONUsageandCharacteristicsJSON核心特点文本格式基于文本,可被任何编程语言读取和处理简洁性语法简洁,使用键值对表示数据,易于理解灵活性可表示数组、对象和基本数据类型(字符串、数字、布尔值)可扩展性对象可以嵌套,允许表示复杂的数据结构跨平台作为文本格式,可在不同系统和网络环境无缝传输Python中使用JSON导入模块importjson序列化:Python对象→JSON字符串data={'name':'Zhangsan','age':30}json_str=json.dumps(data)反序列化:JSON字符串→Python对象data_parsed=json.loads(json_str)网络通信中的应用常用于WebAPI和网络服务,特别是RESTful服务作为HTTP请求和响应的主体,用于客户端和服务器数据交换注意事项只支持文本和基本数据类型,不支持二进制数据数字表示有限制,无法精确表示很大或很小的数字,也无法表示特定格式(日期、时间)大型或复杂数据结构不如二进制序列化格式高效5.3.2XML的使用和特点XMLUsageandCharacteristicsXML核心特点自描述性数据携带描述结构的标签,数据含义更清晰可扩展性用户可自定义标签和数据结构,适应不同需求灵活性擅长表示层次化和嵌套数据结构跨平台文本格式,可在不同系统和网络环境无缝传输国际化支持Unicode,可表示任何语言的字符Python中使用XML导入模块importxml.etree.ElementTreeasET创建XML数据data=ET.Element('data')item=ET.SubElement(data,'item')item.set('name','Zhangsan')item.text='Thisisatest'xml_str=ET.tostring(data)解析XML字符串tree=ET.ElementTree(ET.fromstring(xml_str))root=tree.getroot()网络通信中的应用常用于Web服务和配置文件,尤其是SOAP协议作为HTTP请求和响应的主体,用于客户端和服务器数据交换与JSON的对比格式更冗长,数据大小更大解析通常比JSON更耗时,特别是大型或复杂文档灵活性和复杂性可能导致解析和处理困难,需要更多开发工作5.3.3Protobuf的使用和特点ProtobufUsageandCharacteristicsProtobuf核心特点高效性二进制格式,比XML和JSON更小更快简洁的定义语言使用.proto文件定义数据结构,语法类似C语言跨平台和语言支持支持C++、Java、Python等多种编程语言向后兼容性新旧版本数据定义可以兼容可扩展性可在不破坏已部署程序的情况下添加新字段Protobuf使用流程1定义数据结构syntax="proto3";messagePerson{stringname=1;int32id=2;stringemail=3;}2编译生成代码protoc--python_out=.to3序列化/反序列化frommessage_pb2importPersonperson=Person(name="Zhangsan",id=1234)data=person.SerializeToString()person2.ParseFromString(data)网络通信中的应用非常适合传输结构化数据,二进制格式更紧凑,减少网络带宽使用许多分布式系统和RPC框架(如gRPC)使用Protobuf作为数据交换格式提供高效的数据传输方式,适用于性能敏感的应用注意事项二进制格式,不像JSON和XML那样可读需要使用Protobuf编译器生成数据访问类,增加构建复杂性.proto定义文件需要被所有通信方共享,确保数据结构一致性三种序列化格式对比ComparisonofThreeSerializationFormats特性JSONXMLProtobuf数据大小较小较大(冗长)最小解析速度快较慢最快可读性很好很好不可读(二进制)数据类型支持基本类型文本为主丰富跨语言支持优秀优秀优秀模式定义无DTD/XSD.proto文件向后兼容性有限有限优秀JSON适用场景WebAPI、RESTful服务、轻量级通信、配置文件、数据交换格式XML适用场景严格数据结构、配置文件、SOAP协议、文档存储、复杂数据关系Protobuf适用场景高性能通信、微服务架构、分布式系统、gRPC、性能敏感应用04数据压缩技术DataCompressionTechniques提升网络传输效率的关键技术5.4.1压缩算法概述CompressionAlgorithmOverview无损压缩LosslessCompression压缩和解压缩过程中保留所有原始数据,确保数据完整性适用场景文本文件、源代码、可执行文件数据库、配置文件常用算法DEFLATEZIP,压缩率20-70%LZMA7-Zip,压缩率50-90%BrotliGoogle,压缩率60-95%有损压缩LossyCompression压缩过程中丢弃一些数据,通常是人类感知不到或不太重要的信息适用场景图像、音频、视频等媒体数据一定程度的数据丢失对用户体验影响较小常用算法JPEG图像压缩MP3音频压缩H.264/AVC视频压缩压缩算法的选择因素数据类型不同数据适合不同算法压缩比高压缩比意味着更小文件速度压缩/解压缩速度重要资源消耗CPU和内存资源需求兼容性目标平台正确解压5.4.2Python中的压缩库CompressionLibrariesinPythonzlib提供对DEFLATE压缩算法的支持,是gzip和zip文件中使用的压缩算法importzlibcompressed=press(data,6)decompressed=zlib.decompress(compressed)gzip提供读写.gz文件的功能,广泛用于Unix-like系统importgzipwithgzip.open('file.txt.gz','wb')asf:f.write(data)bz2提供对bzip2压缩算法的支持,使用Burrows-Wheeler变换和哈夫曼编码,压缩率高importbz2compressed_data=press(original_data)decompressed_data=bz2.decompress(compressed_data)lzma实现LZMA压缩算法,压缩率极高但速度较慢,适合压缩大型静态文件importlzmacompressed_data=press(original_data)decompressed_data=lzma.decompress(compressed_data)tarfile提供读写tar归档文件的功能,可与gzip、bzip2或lzma结合使用importtarfilewithtarfile.open('archive.tar.gz','w:gz')astar:tar.add('file.txt')zipfile提供读写zip文件的功能,支持多文件和压缩的归档格式importzipfilewithzipfile.ZipFile('archive.zip','w')aszipf:zipf.write('file.txt')选择合适的压缩库压缩比不同算法提供不同压缩比性能压缩/解压缩速度影响应用兼容性格式与接收方兼容资源消耗CPU和内存资源需求5.4.3压缩数据的网络传输CompressedDataTransmissionoverNetwork压缩前的考虑因素数据类型已压缩的数据(如视频或图片)可能不会从再次压缩中受益CPU开销压缩和解压缩需要额外CPU资源,可能影响服务器性能延迟压缩数据会增加处理时间,可能引入额外延迟带宽与CPU的权衡在带宽受限且CPU资源充足时,压缩更有意义实现网络传输压缩1选择压缩算法根据数据类型和应用需求选择gzip、brotli或lzma2压缩数据在发送前使用选定算法压缩数据3设置HTTP头部使用HTTP时,设置Content-Encoding头部指示数据已被压缩4发送压缩数据将压缩后的数据发送到网络5客户端解压缩接收端根据长度接收数据并进行解压缩安全和最佳实践安全性确保压缩过程不会引入CRIME和BREACH攻击缓存考虑压缩数据的缓存策略,避免重复压缩相同数据内容协商使用内容协商机制,仅在客户端支持时发送压缩数据监控性能监控压缩对性能的影响,确保符合应用性能目标05错误处理和异常ErrorHandlingandExceptions构建健壮的网络应用5.5.1网络异常分类和错误处理策略NetworkExceptionClassificationandErrorHandlingStrategies网络异常分类连接异常•连接失败:无法建立连接,目标服务器不可达•连接重置:对方崩溃或重启•连接超时:网络延迟或服务器响应慢数据传输异常•读取/写入超时、数据损坏协议异常•协议错误、协议不支持资源异常•资源耗尽、资源限制安全异常•认证失败、授权失败错误处理策略异常捕获使用try...except块捕获异常,根据类型进行处理日志记录记录详细错误信息和堆栈跟踪,便于调试用户反馈提供清晰的错误消息和解决方案或重试选项资源清理确保异常发生时释放所有资源(套接字、文件)重试逻辑对临时性错误实现重试,限制次数和间隔故障转移尝试备用服务器或服务维持程序运行重要性:正确处理网络异常对构建健壮和用户友好的网络应用至关重要。开发者需了解不同类型的网络异常,并根据应用需求制定合适的错误处理策略。5.5.2异常捕获和处理最佳实践ExceptionHandlingBestPracticesPython异常捕获基本语法importloggingtry:#网络操作代码passexceptConnectionErrorase:logging.error(f"Connectionerror:{e}")conn.close()exceptExceptionase:logging.error(f"Unexpectederror:{e}")最佳实践具体异常类型捕获,避免空异常处理避免过度捕获(如exceptException)必要时将异常传播给调用者网络请求异常处理示例使用requests库importrequestsdeffetch_data(url):try:response=requests.get(url,timeout=5)response.raise_for_status()returnresponse.textexceptrequests.exceptions.HTTPErrorase:print(f"HTTPerror:{e}")exceptrequests.exceptions.ConnectionErrorase:print(f"Connectionerror:{e}")exceptrequests.exceptions.Timeoutase:print(f"Timeouterror:{e}")returnNone核心原则:正确的异常捕获和处理对构建健壮网络应用至关重要。它不仅防止程序崩溃,还提供有用的调试信息,允许程序在遇到问题时优雅恢复。开发者应根据应用需求和上下文设计合适的异常处理策略。5.5.3错误日志和调试ErrorLoggingandDebugging错误日志记录应用程序运行时发生的错误和异常信息,包括错误消息、时间、堆栈跟踪和上下文信息。记录要点详细性:包含足够信息理解和重现错误一致性:日志格式一致,便于分析和搜索安全性:避免记录敏感信息(密码、个人数据)可访问性:存储在可靠位置,易于访问Pythonlogging模块logging.basicConfig(level=logging.DEBUG,format='%(asctime)s%(levelname)s:%(message)s')logging.error("Unexpectederror",exc_info=True)调试技术打印语句添加print显示变量值或程序状态交互式调试器使用pdb模块或IDE调试器逐步执行代码日志记录使用日志跟踪程序执行流程和状态变化单元测试编写测试验证代码正确性和功能网络应用调试重点•网络通信:监控分析网络请求和响应•并发同步:调试多线程异步代码•性能问题:分析延迟、资源竞争、内存泄露最佳实践定期审查日志定期检查错误日志,及时发现和解决问题使用专业工具利用网络分析和性能监控工具辅助调试持续集成在CI流程中包含代码质量检查和自动化测试本章小结数据序列化理解JSON、XML和Protobuf三种序列化格式的使用方法和特点。JSON适合WebAPI和轻量级通信;XML适合严格数据结构和配置;Protobuf适合高性能和微服务架构。数据压缩了解不同压缩算法(DEFLATE、LZMA、Brotli)及Python压缩库的使用。掌握无损压缩与有损压缩的区别,以及如何在网络传输中有效使用压缩技术。编码和字节序掌握编码转换和处理网络字节顺序的方法。理解Python中字符串和字节类型的区别,以及在网络编程中正确处理字节序的重要性。错误处理学会如何分类、捕获和处理网络异常。采用有效的错误日志记录和调试技术,提高问题解决效率,确保网络应用的稳定性和可靠性。构建高效、稳定且可靠的网络应用通过本章的学习,您应该能够在网络应用中有效地实现数据序列化和压缩,以及处理可能出现的错误和异常。这些知识对于构建现代网络应用至关重要。ComputerNetworks第六章异步编程与协程提升程序性能的关键技术《计算机网络》课程Contents本章目录6.1异步编程概述同步与异步编程模型、异步编程的优势与应用场景6.2协程基础协程的概念、async/await语法、协程执行流程6.3asyncio模块详解事件循环、Task与Future对象、常用API函数6.4异步I/O操作StreamReader/StreamWriter、TCP服务器、Protocol与Transport6.5Web应用开发aiohttp库、HTTP客户端与服务器、WebSocket编程学习目标掌握异步编程核心概念,构建高性能网络应用6.1Chapter6.1异步编程概述理解同步与异步编程的核心差异SyncvsAsync同步编程vs异步编程同步编程同步(Synchronous):程序按照代码书写顺序依次执行,每个操作必须等待前一个操作完成后才能开始。执行特点:•阻塞式执行,一个任务未完成,后续任务只能等待•代码逻辑简单清晰,易于理解和调试•适合CPU密集型任务(如计算、数据处理)异步编程异步(Asynchronous):程序在等待某个操作完成时,可以继续执行其他操作,无需阻塞等待。执行特点:•非阻塞式执行,任务等待期间可执行其他任务•代码逻辑相对复杂,需要处理回调或协程•适合I/O密集型任务(如网络请求、文件读写)执行模型对比同步执行模型任务1任务2任务3顺序执行,前一个任务阻塞时整个程序等待异步执行模型任务1启动任务2执行任务3执行任务1完成任务等待期间可切换执行其他任务,提高执行效率关键差异总结执行方式:同步阻塞vs异步非阻塞资源利用:低vs高编程复杂度:简单vs相对复杂适用场景:CPU密集型vsI/O密集型WhyAsynchronous为什么需要异步编程解决I/O阻塞问题在传统的同步编程中,当程序执行I/O操作(如网络请求、文件读写、数据库查询)时,线程会被阻塞,直到操作完成才能继续执行。这种阻塞会导致CPU资源浪费,程序响应变慢。异步编程通过事件驱动机制,在I/O等待期间释放CPU,让程序可以继续处理其他任务,从而最大化资源利用率。提高并发性能异步编程能够在单线程内处理大量并发连接,相比多线程/多进程模型,具有更低的内存占用和更高的性能表现。特别适合构建高并发的网络应用,如Web服务器、API网关、聊天服务器等,能够同时处理数千甚至数万个并发连接。优化资源利用异步编程减少了线程切换的开销,每个协程的内存占用通常只有几KB,而线程需要几MB。这使得内存使用效率大幅提升,可以创建数以万计的协程而不会耗尽系统资源。异步编程适用场景网络请求HTTP/HTTPS请求、API调用文件操作大文件读写、日志记录数据库操作查询、更新、批量处理实时通信WebSocket、聊天应用Python异步编程演进Python3.4:引入asyncio模块,提供事件循环、协程、任务等基础设施Python3.5:引入async/await语法,简化协程的定义和调用Python3.7+:asyncioAPI稳定,性能持续优化,生态日益完善6.2Chapter6.2协程基础掌握协程的概念与实现机制CoroutineConcept什么是协程协程定义协程(Coroutine)是一种用户态的轻量级线程,可以在单个线程内实现并发执行。与传统的线程不同,协程的调度由程序员控制,而不是由操作系统内核调度。协程可以在执行过程中挂起(suspend),保存当前状态,然后在适当的时候恢复(resume)执行,从挂起的位置继续往下执行。协程的核心特点1.协作式多任务协程主动让出CPU,而非被强制切换,避免了线程上下文切换的开销2.状态保存协程挂起时会保存执行状态(局部变量、指令指针等),恢复时继续执行3.轻量级创建和切换开销极小,一个线程内可创建数万个协程协程vs线程对比项协程线程调度方式用户态调度内核态调度切换开销极低(几十字节)较高(几MB)创建数量数万级别数百级别同步机制无需锁机制需要锁、信号量等编程模型协作式抢占式协程的优势✓高性能:切换开销小,执行效率高✓高并发:支持大量并发任务✓简化编程:避免复杂的线程同步问题✓可预测:执行顺序可控,易于调试async/awaitSyntaxPython中的async/await语法async关键字async用于定义协程函数,将普通函数转换为协程函数。调用协程函数不会立即执行,而是返回一个协程对象。asyncdeffetch_data():print("开始获取数据")awaitasyncio.sleep(1)print("数据获取完成")return"数据"#调用协程函数coroutine=fetch_data()print(type(coroutine))#await关键字await用于等待协程或可等待对象执行完成。它会暂停当前协程的执行,将控制权交还给事件循环,直到等待的对象完成。result=awaitfetch_data()print(result)#输出:数据获取完成#await也可以用于其他可等待对象awaitasyncio.sleep(2)awaitsome_task可等待对象可以被await关键字等待的对象,包括:协程对象调用asyncdef函数返回的对象Task对象使用asyncio.create_task()创建Future对象表示异步操作的最终结果重要规则1.await只能在async函数内部使用2.协程需要通过事件循环运行3.不要忘记await协程对象运行协程#方法1:使用asyncio.run()importasyncioasyncio.run(fetch_data())#方法2:获取事件循环loop=asyncio.get_event_loop()loop.run_until_complete(fetch_data())ExecutionMechanism协程的执行流程协程执行机制1协程对象创建调用asyncdef函数时,不会立即执行,而是返回一个协程对象(coroutineobject)2事件循环调度将协程对象交给事件循环(EventLoop),事件循环负责调度协程的执行3协程挂起当遇到await时,协程会挂起,将控制权交还给事件循环4协程恢复等待的操作完成后,事件循环恢复协程执行,从挂起位置继续代码示例:协程执行流程importasyncioasyncdeftask1():print("Task1:开始")awaitasyncio.sleep(1)#挂起1秒print("Task1:完成")asyncdeftask2():print("Task2:开始")awaitasyncio.sleep(2)#挂起2秒print("Task2:完成")...协程状态PENDING协程已创建但未开始执行,或正在等待调度RUNNING协程正在执行中,占用CPU资源SUSPENDED协程遇到await,暂时挂起,等待操作完成DONE协程执行完成或抛出异常,生命周期结束关键理解•单线程并发:多个协程在单线程内交替执行•非抢占式:协程主动让出CPU,不会被强制中断•事件循环调度:由事件循环统一管理和调度协程输出结果Task1:开始Task2:开始[等待1秒]Task1:完成[再等待1秒]Task2:完成总耗时:2秒6.3Chapter6.3asyncio模块详解深入理解asyncio核心组件asyncioArchitectureasyncio模块架构核心组件事件循环EventLoop是asyncio的核心,负责调度协程、处理I/O事件、管理定时任务协程Coroutine使用asyncdef定义的协程函数,是异步编程的基本单元任务Task是对协程的封装,用于调度协程的执行,是Future的子类未来对象Future表示异步操作的最终结果,可以添加回调函数组件关系图事件循环EventLoop核心调度器任务Task协程调度Future异步结果协程Coroutine异步任务编程模型与执行流程asyncio采用单线程、事件驱动的编程模型。所有协程在单个线程内并发执行,通过事件循环进行调度。执行流程①创建协程对象:调用asyncdef函数②封装为Task:使用asyncio.create_task()或asyncio.ensure_future()③注册到事件循环:Task被添加到事件循环的调度队列④事件循环调度:事件循环选择就绪的Task执行⑤协程执行:Task执行封装的协程,直到遇到await⑥协程挂起:遇到await,协程挂起,控制权交还事件循环⑦等待完成:等待await后面的操作完成⑧协程恢复:操作完成后,事件循环恢复协程执行协作关系事件循环调度中心Task协程封装Future结果占位EventLoop事件循环EventLoop事件循环的工作原理事件循环(EventLoop)是asyncio的核心机制,负责调度协程的执行、处理I/O事件、管理定时器等。它是一个无限循环,不断检查是否有就绪的任务或事件需要处理。核心职责调度协程处理I/O事件管理定时器执行回调函数事件循环的工作流程1检查就绪任务:查看就绪队列中是否有可以执行的协程2执行就绪任务:选择一个就绪的协程执行,直到遇到await3协程挂起:协程遇到await,控制权交还给事件循环4等待事件:等待I/O事件、定时器到期或新任务就绪5恢复协程:等待的操作完成,事件循环恢复协程执行事件循环基本操作#1.获取事件循环loop=asyncio.get_running_loop()#2.运行协程(推荐)asyncio.run(main())#3.创建任务task=loop.create_task(coro())#4.关闭事件循环loop.close()事件循环的优势高效调度:自动管理成千上万个协程非阻塞I/O:充分利用等待时间统一接口:简化异步编程模型事件循环调度示意图事件循环TaskATaskBTaskCTask&FutureTask对象与Future对象Task对象Task是对协程的封装,用于调度协程的执行。Task是Future的子类,它在内部封装了一个协程对象,并负责将其提交给事件循环执行。...asyncdefmy_coroutine():print("Hello")...#创建Tasktask=asyncio.create_task(my_coroutine())#或者task=asyncio.ensure_future(my_coroutine())Future对象Future表示一个异步操作的最终结果。它是一个特殊的可等待对象,代表尚未完成的操作,可以在操作完成后设置结果或异常。#创建Future对象future=asyncio.Future()#设置结果future.set_result("数据")#设置异常future.set_exception(Exception("错误"))#添加回调future.add_done_callback(callback)Task的主要方法cancel()取消任务执行,如果任务已完成则无法取消cancelled()检查任务是否被取消,返回布尔值done()检查任务是否完成,包括正常完成、取消或抛出异常result()获取任务执行结果,如果任务未完成则抛出异常TaskvsFuture关系继承关系:Task是Future的子类封装内容:Task封装协程,Future封装结果使用场景:Task用于调度,Future用于结果CommonAPIsasyncio常用APIasyncio.run()运行协程函数,创建事件循环,执行协程,完成后关闭事件循环。这是运行协程的推荐方式。asyncdefmain():print("Hello")asyncio.run(main())asyncio.create_task()创建Task对象,将协程封装为任务并调度执行。可以并发执行多个协程,不会阻塞当前协程。task1=asyncio.create_task(coro1())task2=asyncio.create_task(coro2())awaittask1...asyncio.gather()并发执行多个协程或任务,等待所有任务完成,返回结果列表。如果某个任务抛出异常,会立即传播。...awaitasyncio.gather(coro1(),coro2(),coro3())asyncio.sleep()异步版本的sleep,不会阻塞事件循环。让出CPU资源,允许其他协程执行。常用于模拟延迟或定时操作。...awaitasyncio.sleep(1)print("1秒后执行")asyncio.wait()等待多个任务完成,可以指定返回条件(ALL_COMPLETED,FIRST_COMPLETED,FIRST_EXCEPTION)。更灵活的等待控制。...done,pending=awaitasyncio.wait(tasks,return_when=asyncio.FIRST_COMPLETED)asyncio.shield()保护协程或任务不被取消。即使父协程被取消,被保护的协程仍会继续执行,直到完成。...awaitasyncio.shield(important_task)#important_task不会被取消asyncio.open_connection()创建TCP连接,返回(reader,writer)元组。用于异步网络编程,实现非阻塞的网络I/O操作。...reader,writer=awaitasyncio.open_connection('',8888)asyncio.start_server()创建TCP服务器,监听指定地址和端口。自动处理客户端连接,为每个连接创建任务。...server=awaitasyncio.start_server(handle_client,'',8888)asyncio.get_event_loop()获取当前线程的事件循环。如果当前线程没有事件循环,则创建一个新的。在异步上下文中使用。...loop=asyncio.get_event_loop()loop.run_until_complete(main())6.4Chapter6.4异步I/O操作掌握异步文件和网络I/O编程StreamsAPIStreamReader与StreamWriterStreamReader与StreamWriterStreamReader和StreamWriter是asyncio提供的高级异步I/O流对象,用于异步网络通信。它们提供了类似文件对象的接口,但完全异步非阻塞。StreamReader用于读取数据的异步流对象•read(n)-读取n个字节•readline()-读取一行•readexactly(n)-精确读取n字节StreamWriter用于写入数据的异步流对象•write(data)-写入数据•drain()-刷新缓冲区•close()-关闭连接创建连接...asyncdeftcp_client():reader,writer=awaitasyncio.open_connection('',8888)#使用reader和writer进行通信...TCP客户端完整示例importasyncioasyncdeftcp_echo_client():reader,writer=awaitasyncio.open_connection('',8888)print('Sending...')writer.write(b'Hello!')awaitwriter.drain()data=awaitreader.read(100)print(f'Received:{data.decode()}')writer.close()awaitwriter.wait_closed()asyncio.run(tcp_echo_client())关键方法说明writer.drain()必须调用,用于刷新写缓冲区,确保数据发送出去writer.wait_closed()等待连接完全关闭,异步关闭需要awaitTCPServer异步TCP服务器asyncio.start_server()asyncio.start_server()用于创建异步TCP服务器,监听指定的地址和端口,接收客户端连接。当有客户端连接时,自动为每个连接创建一个任务来执行处理函数。...server=awaitasyncio.start_server(handle_client,'',8888)客户端处理函数客户端处理函数是一个协程函数,接收reader和writer参数,用于与客户端通信。每个客户端连接都会创建一个独立的任务来执行此函数,实现并发处理。asyncdefhandle_client(reader,writer):#处理客户端连接data=awaitreader.read(100)writer.write(data)awaitwriter.drain()writer.close()完整服务器示例importasyncioasyncdefhandle_client(reader,writer):addr=writer.get_extra_info('peername')print(f"Clientconnected:{addr}")try:whileTrue:data=awaitreader.read(100)ifnotdata:breakmessage=data.decode()print(f"Received:{message}from{addr}")writer.write(data)awaitwriter.drain()exceptasyncio.CancelledError:print(f"Clientdisconnected:{addr}")finally:writer.close()awaitwriter.wait_closed()asyncdefmain():server=awaitasyncio.start_server(handle_client,'',8888)addr=server.sockets[0].getsockname()print(f'Servingon{addr}')asyncwithserver:awaitserver.serve_forever()asyncio.run(main())并发处理原理每个客户端独立任务:为每个连接创建Task单线程高并发:数千客户端同时连接非阻塞I/O:读写操作不阻塞服务器Low-LevelAPIProtocol与TransportProtocol与TransportProtocol和Transport是asyncio的低层API,提供对网络通信更精细的控制。Protocol负责协议逻辑,Transport负责数据传输。Protocolconnection_made()-连接建立data_received()-数据接收connection_lost()-连接关闭Transportwrite(data)-发送数据close()-关闭连接get_extra_info()-获取信息Protocol示例classEchoProtocol(asyncio.Protocol):defconnection_made(self,transport):self.transport=transportprint("Connectionestablished")defdata_received(self,data):print(f"Received:{data.decode()}")self.transport.write(data)defconnection_lost(self,exc):print("Connectionclosed")创建服务器...asyncdefmain():loop=asyncio.get_running_loop()server=awaitloop.create_server(lambda:EchoProtocol(),'',8888)asyncwithserver:awaitserver.serve_forever()Transport方法write(data):发送数据close():关闭连接get_extra_info():获取对等地址等信息对比:StreamsvsProtocol/Transport特性StreamsProtocol抽象层级高层API低层API编程模型线性、直观事件驱动使用难度简单较复杂6.5Chapter6.5Web应用开发使用aiohttp构建异步Web应用aiohttpFrameworkaiohttp库介绍什么是aiohttpaiohttp是基于asyncio的异步HTTP客户端/服务器框架,提供完整的Web开发功能,支持HTTP/HTTPS、WebSocket、会话管理、路由等。主要特性高性能:基于asyncio,单线程支持高并发WebSocket支持:内置WebSocket支持,实时双向通信会话管理:支持Cookie和会话,管理用户状态灵活路由:支持URL路由和视图函数安装aiohttppipinstallaiohttpaiohttpvsFlask/Django特性aiohttpFlask/Django编程模型异步同步WSGI并发能力高(单线程)依赖多线程性能优秀良好学习曲线中等简单适用场景高并发API、实时应用传统Web应用选择建议✓选择aiohttp:构建高并发API、实时应用、微服务、需要处理大量并发连接的场景✓选择Flask/Django:传统Web应用、快速原型开发、团队对同步编程更熟悉的情况HTTPClientaiohttp客户端编程ClientSessionClientSession是aiohttp客户端的核心类,用于管理HTTP连接。它支持连接复用、Cookie持久化、自定义请求头等高级功能。推荐使用asyncwith管理Session生命周期。importaiohttpimportasyncioasyncdeffetch_url(session,url):asyncwithsession.get(url)asresponse:returnawaitresponse.text()asyncdefmain():asyncwithaiohttp.ClientSession()assession:html=awaitfetch_url(session,'')print(html)常用请求方法awaitsession.get(url,params={...})awaitsession.post(url,data={...})awaitsession.put(url,json={...})高级功能示例...asyncdefadvanced_request():timeout=aiohttp.ClientTimeout(total=10)headers={'User-Agent':'MyBot/1.0'}asyncwithaiohttp.ClientSession(timeout=timeout,headers=headers)assession:asyncwithsession.get('')asresp:print(f'Status:{resp.status}')print(f'Content-Type:{resp.headers["content-type"]}')json_data=awaitresp.json()returnjson_data并发请求示例...asyncdeffetch_many(urls):asyncwithaiohttp.ClientSession()assession:tasks=[fetch_url(session,url)forurlinurls]results=awaitasyncio.gather(*tasks)returnresultsResponse对象常用方法•text()-文本•json()-JSON对象•read()-原始字节•status-状态码HTTPServeraiohttp服务器端编程Web.Applicationweb.Application是aiohttp服务器端的核心类,用于创建Web应用实例。它负责路由管理、中间件注册、应用配置等功能。fromaiohttpimportwebasyncdefhandle_request(request):returnweb.Response(text="Hello,World")app=web.Application()app.router.add_get('/',handle_request)路由定义app.router.add_get('/',handler)#GETapp.router.add_post('/',handler)#POSTapp.router.add_put('/',handler)#PUTapp.router.add_delete('/',handler)#DELETE完整Web服务器示例fromaiohttpimportwebimportasyncioasyncdefhandle_hello(request):returnweb.Response(text="Hello,World!")asyncdefhandle_user(request):user_id=request.match_info['user_id']returnweb.Response(text=f"UserID:{user_id}")asyncdefhandle_post(request):data=awaitrequest.post()returnweb.json_response({"status":"success"})definit_app():app=web.Application()app.router.add_get('/',handle_hello)app.router.ad

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论