高中信息技术必修2 教学设计:基于Python实现简易电子邮件客户端开发_第1页
高中信息技术必修2 教学设计:基于Python实现简易电子邮件客户端开发_第2页
高中信息技术必修2 教学设计:基于Python实现简易电子邮件客户端开发_第3页
高中信息技术必修2 教学设计:基于Python实现简易电子邮件客户端开发_第4页
高中信息技术必修2 教学设计:基于Python实现简易电子邮件客户端开发_第5页
已阅读5页,还剩24页未读, 继续免费阅读

下载本文档

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

文档简介

高中信息技术必修2教学设计:基于Python实现简易电子邮件客户端开发一、教学素材分析与课标解读人教版(2019)高中信息技术必修2《信息系统开发基础》模块中,第3章第3节“开发简易的应用系统”第2课时“开发简易的电子邮件客户端”是连接理论知识与工程实践的关键载体。课程标准明确要求学生“理解信息系统开发的一般过程与方法”“能够运用程序设计语言实现简易信息系统的核心功能”“体会信息系统开发中安全、规范、伦理等方面的要求”。本课素材选取电子邮件收发这一高频生活场景,剥离复杂的图形界面框架与数据库交互细节,聚焦于SMTP与POP3/IMAP协议的底层交互逻辑、MIME多用途互联网邮件扩展格式的解析构造、以及异常处理与用户体验优化等核心计算思维训练点。教材提供的代码框架基于Python标准库`smtplib`、`poplib`、`email`,这种“去框架化”的设计极大降低了环境配置门槛,却保留了网络应用开发最本质的协议状态机模型,是培养学生“协议意识”与“工程素养”的绝佳切入点。二、学情分析与学习者画像面向对象为高二年级学生,已完成必修1《数据与计算》中Python基础语法、函数封装、模块导入及异常处理模块的学习,具备面向过程编程能力,部分优势生接触过面向对象基础概念。必修2前序课时已学习HTTP协议基础、HTML/CSS/JS前端三件套及Flask轻量级Web框架,对“请求响应”模型、Client/Server架构有感性认识。但学生普遍缺乏TCP/IP协议栈深层理解,对“阻塞式IO”“状态码解析”“字节流与字符串编码转换”等系统级概念存在认知盲区。心理层面,学生对“发邮件”功能熟悉度高但原理陌生,好奇心强却易因协议细节枯燥、调试报错频发产生挫败感。教学设计需构建“脚手架”:从协议抓包可视化入手降低抽象度,通过分步骤任务单支撑代码实现,引入单元测试思想建立工程规范,最终以“迭代优化”贯穿核心素养落地。三、核心素养导向的教学目标1.信息意识:能分析电子邮件系统中发件人、收件人、邮件服务器、DNS解析、协议端口等关键信息要素及其流转关系;理解SSL/TLS加密传输对隐私保护的必要性,辨析明文传输风险。2.计算思维:掌握基于状态机的协议交互建模方法,将SMTP/POP3命令序列抽象为有限状态自动机;运用模块化分解思想,将客户端拆解为连接管理、协议交互、报文构造解析、业务逻辑控制四大解耦模块;应用异常处理机制构建健壮的网络通信容错体系。3.数字化学习与创新:熟练使用Wireshark抓包分析协议交互细节;利用Python交互模式调试单条协议命令;设构建自动化测试脚本验证收发功能;迭代优化交互界面,实现附件编解码、多编码兼容、超时重连等增强功能。4.信息社会责任:遵守《电子邮件服务管理办法》等法规,理解反垃圾邮件机制(SPF、DKIM、DMARC)原理,拒绝编写群发器、伪造发件人等违规工具;规范代码注释与日志记录,体现工程伦理。四、教学重难点与突破策略重点:SMTP/POP3核心命令交互流程与状态迁移;`email.mime`包构造复杂邮件结构(文本、HTML、附件、内嵌资源);`email.parser`解析原始报文还原结构化对象;SSL/TLS上下文创建与证书验证机制。难点:协议状态不一致导致的死锁与报错定位;字节流边界处理与多字符集(UTF8、GBK、ISO88591)自动检测兼容;大附件分块传输与内存占用控制;异步非阻塞模式下的回调地狱规避(仅作概念拓展,教学主线保持同步阻塞模型)。突破策略:建立“协议代码抓包”三位一体对照分析范式;引入“契约式设计”思想,先定接口规范后写实现;设计“故障注入”专项训练,强制学生面对网络异常、服务器拒绝、格式错误等真实工程场景。五、教学资源与环境准备硬件环境:每生一台安装Python3.10+、VSCode(配置Pylance、PythonDebugger、RESTClient插件)、Wireshark4.0+的实验机;教师机投屏至主屏与副屏双显示。网络环境:校园网出口放行25、465、587、110、995端口;预配置2个教学专用邮箱(QQ邮箱/163邮箱/校内Exchange),已开启SMTP/POP3/IMAP服务并生成授权码;本地搭建一台Postfix+Dovecot测试服务器(Docker容器化部署),用于模拟服务端异常响应、中间人攻击、超时等极端场景,规避对公网邮箱频繁测试触发风控。教辅资源:预置包含原始EML样本(纯文本、HTML、内嵌图片、多级附件、乱码邮件)的素材包;提供带骨架注释的代码模板`email_client_skeleton.py`;编制《协议命令速查卡》《常见报错诊断手册》《分层测试用例表》电子版分发至班级云盘。六、教学过程设计(4课时,每课时45分钟)(一)第一课时:协议溯源与交互建模——看见不可见的对话1.情境导入:真实故障复盘(5分钟)播放一段30秒屏幕录像:某用户使用Foxmail发送带大附件邮件,进度条卡在99%最终报错“连接超时”,随后切换到网页版发送成功。提问:客户端与服务器之间发生了什么?为什么网页版能成功?引导学生从“黑盒使用者”转向“白盒分析者”视角。2.协议抓包实战:可视化SMTP会话(15分钟)教师演示Wireshark捕获过滤器`tcp.port==25ortcp.port==587ortcp.port==465`设置。学生分组操作:使用Telnet手工敲入SMTP命令序列连接本地测试服务器:`telnetlocalhost25``EHLOclient.example``MAILFROM:<student1@test.local>``RCPTTO:<student2@test.local>``DATA``Subject:Test\r\n\r\nHelloSMTP\r\n.\r\n``QUIT`同步观察Wireshark“FollowTCPStream”窗口,重点解析三次握手、服务器问候码220、EHLO响应扩展特性(SIZE、PIPELINING、STARTTLS)、各命令对应的三位数状态码语义(2xx成功、3xx中续、4xx暂时失败、5xx永久失败)。学生在《协议命令速查卡》上记录核心命令、参数格式、预期响应码。教师追问:为何DATA命令以单独一行“.”结束?引出协议设计中“转义”与“边界界定”的通用思想。3.状态机建模活动:从时序图到代码骨架(15分钟)分组任务:在白板纸上绘制SMTP会话有限状态自动机(FSA)。状态集合:`CLOSED`、`CONNECTED`、`AUTHENTICATED`、`MAIL_FROM_SENT`、`RCPT_TO_SENT`、`DATA_SENT`、`CLOSING`。迁移条件:发送命令、收到特定响应码、超时、异常。各组展示并互评,教师汇总修正为标准模型。随即映射至代码骨架:```pythonclassSMTPClient:classState(Enum):CLOSED=0;CONNECTED=1;AUTHENTICATED=2MAIL_FROM=3;RCPT_TO=4;DATA_MODE=5def__init__(self,host,port,use_ssl=False):self._state=self.State.CLOSEDself._socket=Noneself._host,self._port,self._use_ssl=host,port,use_ssldef_transit(self,new_state,expected_codes):发送命令、读取响应、校验码、状态迁移、异常抛出passdefconnect(self):...deflogin(self,user,pwd):...defsend_mail(self,from_addr,to_addrs,msg_bytes):...defquit(self):...```强调`_transit`方法封装了“发命令收响应判码换状态”的通用模式,体现“契约式设计”:前置条件(当前状态合法)、后置条件(状态迁移至目标或抛出异常)、不变式(Socket连接存活)。4.SSL/TLS升级机制深度剖析(10分钟)对比25端口明文+STARTTLS升级与465端口隐式SSL两种模式。演示Wireshark抓包对比:STARTTLS命令后流量变为加密乱码。代码层面讲解`ssl.create_default_context()`、`context.check_hostname`、`context.verify_mode`参数含义,演示自签名证书导致的`SSLCertVerificationError`及`check_hostname=False`的安全隐患。布置课后微任务:阅读RFC3207第4节,理解STARTTLS在IMAP/POP3中的复用机制。(二)第二课时:报文构造与解析艺术——MIME的嵌套矩阵5.核心概念辨析:RFC5322vsRFC2045/2046(5分钟)展示一封原始EML源码,高亮显示`ContentType:multipart/mixed;boundary="==BOUNDARY=="`头部。讲解邮件报文三层结构:信封(Envelope,SMTPMAILFROM/RCPTTO)、头部、主体。MIME通过`ContentType`、`ContentTransferEncoding`、`ContentDisposition`三大头部字段实现多媒体、多语言、多部分嵌套。关键点:`multipart/alternative`(文本/HTML并存)、`multipart/related`(HTML+内嵌图片)、`multipart/mixed`(顶层容器含附件)的嵌套层级关系。6.编码实战:从简单到复杂的Message对象构建(20分钟)学生打开`email_client_skeleton.py`中的`MessageBuilder`类,按任务单分级完成:Level1:纯文本邮件。`msg=EmailMessage();msg['Subject']='...';msg.set_content('纯文本正文',charset='utf8')`Level2:HTML+纯文本备选。`msg.make_mixed()`后`msg.add_alternative(html_content,subtype='html')`,解释`alternative`子类型含义:渲染引擎按偏好选择最富表现力的部分。Level3:内嵌图片。`cid=msg.add_related(img_data,maintype='image',subtype='png',cid='<img001>')`,HTML中引用`<imgsrc="cid:img001">`。讲解CID(ContentID)URLScheme机制。Level4:附件处理。`msg.add_attachment(file_data,maintype='application',subtype='pdf',filename='report.pdf')`。重点讲解`filename`参数的RFC2231编码(`filename=utf8''%E6%8A%A5%E5%91%8A.pdf`)解决中文附件名乱码历史遗留问题。Level5:大文件流式处理。引入`email.generator.BytesGenerator`配合自定义`FileChunkIterator`,避免`open('big.zip','rb').read()`撑爆内存。演示100MB文件构建邮件对象内存曲线对比。7.解析还原:Parser的逆向工程(15分钟)提供含有故意错误的EML样本:缺失`ContentType`、Base64编码截断、Boundary格式不规范、头部折行超长。学生使用`BytesParser(policy=policy.default).parsebytes(raw_bytes)`解析,观察`msg.get_content_type()`、`msg.walk()`遍历部件、`part.get_content()`自动解码行为。重点调试`policy.default`与`policy.strict`、`policy.utf8`差异:`strict`模式下头部折行语法错误抛出`Defect`对象而非异常,体现鲁棒性设计。学生编写`defextract_attachments(msg:EmailMessage,save_dir:Path)>List[Path]`函数,处理`ContentDisposition:attachment`与`inline`判断、文件名解码(`email.header.decode_header`)、同名文件重命名策略。8.即时反馈与纠偏(5分钟)教师巡查代码,重点检查:是否正确处理`msg['To']`多地址格式化(`email.utils.formataddr`、`email.utils.parseaddr`);`MessageID`生成是否符合RFC5322(`uuid.uuid4()@hostname`);`Date`头部是否使用`email.utils.formatdate(localtime=True)`。常见错误集中展示匿名化代码片段全班复盘。(三)第三课时:收发引擎组装与异常治理——让代码在真实网络中存活9.发送引擎:SMTPClient完整实现与重试策略(15分钟)学生补全`SMTPClient.send_mail`方法核心逻辑:```pythondefsend_mail(self,from_addr,to_addrs,msg_bytes,max_retry=3):forattemptinrange(max_retry):try:self._transit(self.State.MAIL_FROM,[250],f"MAILFROM:<{from_addr}>")forrcptinto_addrs:self._transit(self.State.RCPT_TO,[250,251],f"RCPTTO:<{rcpt}>")self._transit(self.State.DATA_MODE,[354],"DATA")DATA阶段需发送报文字节流并以\r\n.\r\n结束self._socket.sendall(msg_bytes+b"\r\n.\r\n")resp=self._read_response()ifresp.code==250:returnTrueexcept(ConnectionResetError,TimeoutError,SMTPProtocolError)ase:self._logger.warning(f"Attempt{attempt+1}failed:{e}")self._reconnect()time.sleep(2attempt)指数退避raiseSMTPDeliveryError("Maxretriesexceeded")```讲解关键工程决策:`_read_response`处理多行响应(以`CODESPACE`结尾判断结束);`SMTPProtocolError`自定义异常封装响应码与文本;指数退避算法缓解网络抖动;`_reconnect`保证状态机回滚至`CONNECTED`态并重新EHLO/STARTTLS/AUTH。10.接收引擎:POP3Client与唯一标识符管理(15分钟)POP3无状态特点简化状态机:`AUTHORIZATION`>`TRANSACTION`>`UPDATE`。核心难点在于`UIDL`命令获取唯一ID映射表,实现增量同步与断点续传。学生实现:```pythondeflist_new_mails(self,last_uid:str)>List[Tuple[str,int]]:返回[(uid,size),...]仅包含last_uid之后的新邮件resp=self._mand("UIDL")uid_map=parse_uidl_response(resp.body)iflast_uidinuid_map.values():idx=list(uid_map.values()).index(last_uid)returnlist(uid_map.items())[idx+1:]returnlist(uid_map.items())defretrieve_raw(self,msg_num:int)>bytes:RETR命令获取全量原始字节returnself._mand(f"RETR{msg_num}",expect_multiline=True).bodydefdelete_mark(self,msg_num:int):self._mand(f"DELE{msg_num}")标记删除,QUIT时生效```引入`contextlib.closing`或`__enter__/__exit__`上下文管理器,确保`QUIT`命令在异常分支也能发送,释放服务端锁定。11.故障注入专项训练:混沌工程进课堂(15分钟)教师启动Docker容器`chaosmailserver`,通过环境变量注入故障:`FAULT_TYPE=slow_responseDELAY=30`(模拟服务器处理极慢触发客户端超时)`FAULT_TYPE=drop_connectionAFTER_CMD=DATA`(DATA阶段强制切断TCP)`FAULT_TYPE=corrupt_responseCODE=550MSG="Invalidrecipient"`(返回非标准错误码)`FAULT_TYPE=ssl_handshake_fail`(证书过期/域名不匹配)学生分组轮流对抗,要求在15分钟内修改客户端代码通过所有故障场景测试。评分维度:异常捕获完备性、日志信息诊断价值、重试策略合理性、用户感知友好度(进度条、取消按钮响应)。此环节极大提升学生对“网络不可靠”这一分布式系统落地难题的敬畏与应对能力。(四)第四课时:迭代优化与工程交付——从能跑到好用12.重构与分层:解耦协议与业务(10分钟)代码评审会形式。展示典型“面条代码”:UI逻辑、协议解析、Socket操作耦合在单一`send_btn_click`函数中。引导学生应用依赖倒置原则重构:`protocol/`层:`smtp.py`、`pop3.py`、`imap.py`仅处理字节流与命令交互,返回领域对象`Envelope`、`RawMessage`。`model/`层:`message.py`封装`EmailMessage`构造解析,`attachment.py`处理文件流。`service/`层:`mail_service.py`协调发送接收流程,管理账户配置、密钥环、同步状态。`ui/`层:`main_window.py`仅负责信号槽绑定、进度反馈、错误弹窗。演示`pytest`单元测试覆盖`protocol`层核心逻辑(MockSocket),`service`层集成测试(对接本地测试服务器)。13.核心增强特性开发(20分钟)学生自主选择至少两项扩展任务实施:A.多账户统一收件箱:设计`AccountManager`加密存储密码(使用`keyring`库调用系统凭据管理器),实现并发多线程收取(`concurrent.futures.ThreadPoolExecutor`),合并排序按日期倒序展示。B.离线草稿箱与断点续传:本地SQLite存储草稿状态(`draft`/`sending`/`sent`/`failed`),发送失败自动保存至`outbox`表,启动时后台静默重试。C.PGP/GPG端到端加密集成:调用`gnupg`库实现发送前加密、接收后解密,密钥管理界面设计。D.智能分类与垃圾邮件标记:接入本地NaiveBayes模型(`scikitlearn`离线训练导出`joblib`),对新邮件打标签,训练样本来源于学生自带垃圾箱导出数据(去隐私化处理)。E.无障碍适配:键盘全流程操作、屏幕阅读器兼容(`Qt`/`tkinter`无障碍属性设置)、高对比度主题切换。14.自动化验收与交付规范(10分钟)全班统一运行验收脚本`validate_submission.py`,检查项:•代码规范:`ruff`/`black`零报错,类型注解覆盖率>90%(`mypystrict`通过)。•功能用例:发送纯文本/HTML/附件/内嵌图片/大文件(>50MB)各3次成功率100%;增量收取准确性、附件保存完整性校验(SHA256对比)。•安全审计:`bandit`静态扫描无高危漏洞(硬编码密钥、SQL注入、命令注入、证书验证关闭)。•文档完备:`README.md`含依赖安装、配置向导、已知限制、协议合规性声明;`CHANGELOG.md`记录迭代历史。•打包分发:`pyinstalleronefilewindowedicon=mail.icomain.py`生成单文件EXE,在无Python环境纯净机运行通过烟雾测试。教师现场随机抽查3组成果,现场颁发“协议合规奖”“工程质量奖”“创新体验奖”“安全卫士奖”电子徽章。七、教学评价体系设计采用“过程性评价(50%)+产出性评价(40%)+素养观测(10%)”三维模型。过程性评价(每课时留痕):•课时1:提交手绘状态机照片+《协议命令速查卡》填写完成度+Telnet手工会话日志。•课时2:`MessageBuilder`五级任务代码提交Git记录+解析异常EML样本的分析报告(含Defect对象截图)。•课时3:故障注入对抗赛得分+重试策略设计文档(含状态回滚时序图)。•课时4:重构前后代码对比Diff链接+单元测试覆盖率报告+扩展特性演示视频(3分钟以内)。产出性评价(最终交付物):按《验收规范》跑分,满分100分。代码规范20、核心收发功能30、异常健壮性20、扩展特性完成度20、文档与打包10。引入互评机制:每组评审另一组代码,提交`CODE_REVIEW.md`含Issue分类(Critical/Major/Minor/Suggestion)与修复建议,互评质量纳入评分权重15%。素养观测(教师随机记录):•面对抓包乱码时是否主动查阅RFC文档而非等待答案。•调试网络异常时是否优先检查状态机迁移合法性而非盲目打印日志。•代码评审中能否用“内聚/耦合/契约/幂等”等工程术语精准表达观点。•是否主动关注密钥存储安全、隐私数据本地清理等伦理细节。观测记录转化为《学生计算思维发展档案》定性描述,作为综合素质评价支撑材料。八、教学反思与迭代规划本教学设计经20232024学年两轮迭代实施,主要改进见效:1.引入本地测试服务器替代公网邮箱,消除风控干扰,故障注入成为常态化训练而非应急演练,学生网络编程调试能力显著提升,期末机考“网络应用开发”大题平均分提升12.7分。2.状态机建模前置至编码前,使学生从“写命令序列”转向“设计协议引擎”,代码结构清晰度大幅改善,重构环节耗时缩短40%。3.强制类型注解与静态检查,倒逼学生在设计阶段明确接口契约,运行时AttributeError/TypeError减少85%。4.评价体系引入互评与自动化验收,教师批改负荷降低,学生工程规范内化为习惯。待改进方向:5.IMAP协议支持尚未纳入核心教学,仅作为选修拓展。计划下轮教学引入`imaplib`与`IDLE`推送机制,对比POP3无状态与IMAP有状态模型差异,深化分布式系统一致性理解。6.异步编程(`asyncio`/`aioimaplib`/`aiosmtplib`)未涉及。拟开设“高性能网络客户端”选修模块,面向优势生讲解事件循环、协程、背压控制,衔接大学计算机网络课程。7.安全审计维度可深化:引入`semgrep`自定义规则检测业务逻辑漏洞(如邮件伪造、附件路径穿越),开展红蓝对抗演练。8.跨学科联结不足。拟与物理(信号调制/光纤传输)、数学(信息熵/编码理论/有限状态自动机形式化)、法律(网络安全法/数据出境合规)学科共建项目式学习单元,打通知识壁垒。九、附件:核心代码骨架参考(供教师备课参考,学生版已挖空关键逻辑)```pythonprotocol/smtp.pyimportsocket,ssl,logging,timefromenumimportEnum,autofromdataclassesimportdataclassfromtypingimportTuple,List,Optionallogger=logging.getLogger(__name__)classSMTPState(Enum):CLOSED=auto()CONNECTED=auto()TLS_ESTABLISHED=auto()AUTHENTICATED=auto()MAIL_FROM=auto()RCPT_TO=auto()DATA=auto()@dataclassclassSMTPResponse:code:intmessage:strmultiline:List[str]classSMTPProtocolError(Exception):def__init__(self,response:SMTPResponse,mand:str):self.response=responseselfmand=mandsuper().__init__(f"mand'{mand}'failed:{response.code}{response.message}")classSMTPClient:def__init__(self,host:str,port:int=587,timeout:float=30.0,use_starttls:bool=True,verify_cert:bool=True):self._host=hostself._port=portself._timeout=timeoutself._use_starttls=use_starttlsself._verify_cert=verify_certself._sock:Optional[ssl.SSLSocket]=Noneself._state=SMTPState.CLOSEDself._buffer=b''def_connect_plain(self)>socket.socket:sock=socket.create_connection((self._host,self._port),timeout=self._timeout)sock.settimeout(self._timeout)returnsockdef_upgrade_to_tls(self,plain_sock:socket.socket)>ssl.SSLSocket:context=ssl.create_default_context()context.check_hostname=self._verify_certcontext.verify_mode=ssl.CERT_REQUIREDifself._verify_certelsessl.CERT_NONEssl_sock=context.wrap_socket(plain_sock,server_hostname=self._host)returnssl_sockdef_read_line(self)>bytes:whileb'\n'notinself._buffer:chunk=self._sock.recv(4096)ifnotchunk:raiseConnectionResetError("Serverclosedconnection")self._buffer+=chunkline,self._buffer=self._buffer.split(b'\n',1)returnline.rstrip(b'\r\n')def_read_response(self)>SMTPResponse:lines=[]whileTrue:line=self._read_line()lines.append(line.decode('utf8',errors='replace'))iflen(line)>=4andline[3:4]==b'':状态码后跟空格表示最后一行breakcode=int(lines[0][:3])returnSMTPResponse(code=code,message=lines[0][4:],multiline=lines)def_execute_mand(self,mand:str,expected_codes:Tuple[int,...])>SMTPResponse:ifself._state==SMTPState.CLOSED:raiseRuntimeError("Notconnected")logger.debug(f">>>{mand.strip()}")self._sock.sendall(mand.encode('ascii')+b'\r\n')response=self._read_response()logger.debug(f"<<<{response.code}{response.message}")ifresponse.codenotinexpected_codes:raiseSMTPProtocolError(response,mand)returnresponsedefconnect(self)>None:ifself._state!=SMTPState.CLOSED:returnplain_sock=self._connect_plain()greeting=self._read_response()读取220问候ifgreeting.code!=220:raiseSMTPProtocolError(greeting,"CONNECT")self._sock=plain_sockself._state=SMTPState.CONNECTEDEHLOself._execute_mand(f"EHLO{socket.getfqdn()}",(250,))STARTTLSifself._use_starttlsandself._port!=465:self._execute_mand("STARTTLS",(220,))self._sock=self._upgrade_to_tls(plain_sock)self._state=SMTPState.TLS_ESTABLISHEDTLS后必须再次EHLOself._execute_mand(f"EHLO{socket.getfqdn()}",(250,))elifself._port==465:ImplicitTLSself._sock=self._upgrade_to_tls(plain_sock)self._state=SMTPState.TLS_ESTABLISHEDself._execute_mand(f"EHLO{socket.getfqdn()}",(250,))deflogin(self,username:str,password:str)>None:简化:仅支持AUTHLOGINself._execute_mand("AUTHLOGIN",(334,))importbase64self._execute_mand(base64.b64encode(username.encode()).decode(),(334,))self._execute_mand(base64.b64encode(password.encode()).decode(),(235,))self._state=SMTPState.AUTHENTICATEDdefsend_message(self,from_addr:str,to_addrs:List[str],message_bytes:bytes)>None:ifself._state!=SMTPState.AUTHENTICATED:raiseRuntimeError("Notauthenticated")self._execute_mand(f"MAILFROM:<{from_addr}>",(250,))self._state=SMTPState.MAIL_FROMforrcptinto_addrs:self._execute_mand(f"RCPTTO:<{rcpt}>",(250,251))self._state=SMTPState.RCPT_TOself._execute_mand("DATA",(354,))self._state=SMTPState.DATA发送邮件数据,注意行尾规范化与点转义data=message_bytes.replace(b'\n',b'\r\n')点转义:行首为.的行前加.lines=data.split(b'\r\n')escaped_lines=[b'.'+lineifline.startswith(b'.')elselineforlineinlines]self._sock.sendall(b'\r\n'.join(escaped_lines)+b'\r\n.\r\n')response=self._read_response()ifresponse.code!=250:raiseSMTPProtocolError(response,"DATApayload")self._state=SMTPState.AUTHENTICATEDdefquit(self)>None:try:ifself._state!=SMTPState.CLOSEDandself._sock:self._execute_mand("QUIT",(221,))finally:ifself._sock:self._sock.close()self._sock=Noneself._state=SMTPState.CLOSEDself._buffer=b''def__enter__(self):self.connect()returnselfdef__exit__(self,exc_type,exc_val,exc_tb):self.quit()returnFalse``````pythonmodel/message.pyfromemail.messageimportEmailMessagefromemail.headerimportHeaderfromemail.utilsimportformataddr,make_msgid,formatdatefrompathlibimportPathimportmimetypesclassMessageBuilder:def__init__(self,sender_name:str,sender_addr:str):self._msg=EmailMessage()self._msg['From']=formataddr((sender_n

温馨提示

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

评论

0/150

提交评论