解决使用Golang的email库发送qq邮件报错short response,错误类型为textproto.ProtocolError
问题阐述
使用email库发送QQ邮件,采用465端口:
package mainimport ("fmt""net/smtp""github.com/jordan-wright/email"
)func SendEmail(sendTo string, subject string, body string) (err error) {e := email.NewEmail()// 设置发送方的邮箱e.From = "193*******@qq.com"// 设置接收方的邮箱e.To = []string{sendTo}// 设置主题e.Subject = subject// 设置文件发送的内容e.Text = []byte(body)// e.HTML = []byte(body)// 设置服务器相关的配置err = e.Send(fmt.Sprintf("%s:%d", "smtp.qq.com", 587), smtp.PlainAuth("", "193*******@qq.com", "sdacdf********", "smtp.qq.com"))return
}
func main() {err := SendEmail("wwwwwwww@gmail.com", "测试主题",fmt.Sprintf("您的验证码为:%s,请勿泄露于他人!该验证码5分钟内有效!如非本人操作,请忽略此邮件!", "123456"))if err != nil {fmt.Println("发送验证码失败:", err)//打印错误类型fmt.Printf("%T\n", err)return}fmt.Println("发送验证码成功")
}
控制台输出下面的内容:
发送验证码失败: short response: 一串乱码
textproto.ProtocolError
但是收到了验证码:
可能的原因
因为在SMTP发送过程中出现了意料之外的响应情况,可能是因为连接问题、网络不稳定,或是由于服务器的一些特定限制导致的短响应。尽管服务器响应中断,邮件实际上已经发送成功。
debug过程
尝试改用465加密(ssl)端口:
package mainimport ("crypto/tls""fmt""net/smtp""github.com/jordan-wright/email"
)func SendEmail(sendTo string, subject string, body string) (err error) {e := email.NewEmail()// 设置发送方的邮箱e.From = "193*******@qq.com"// 设置接收方的邮箱e.To = []string{sendTo}// 设置主题e.Subject = subject// 设置文件发送的内容e.Text = []byte(body)// e.HTML = []byte(body)// 设置服务器相关的配置// 使用 SSL 端口 465 并配置 TLStlsConfig := &tls.Config{InsecureSkipVerify: true,ServerName: "smtp.qq.com",}err = e.SendWithTLS(fmt.Sprintf("%s:%d", "smtp.qq.com", 465), smtp.PlainAuth("", "193*******@qq.com", "sdacdf********", "smtp.qq.com"), tlsConfig)return
}func main() {err := SendEmail("wwwwwwww@gmail.com", "测试主题",fmt.Sprintf("您的验证码为:%s,请勿泄露于他人!该验证码5分钟内有效!如非本人操作,请忽略此邮件!", "123456"))if err != nil {fmt.Println("发送验证码失败:", err)//打印错误类型fmt.Printf("%T\n", err)return}fmt.Println("发送验证码成功")
}
还是报相同的错误,能够收到邮件,遂放弃封装好的email库,使用原始的smtp库,但是采用不加密的587端口:
package mainimport ("fmt""net/smtp"
)func SendEmail(sendTo string, subject string, body string) error {from := "193*******@qq.com"password := "dsfdfcf******" // 邮箱授权码smtpServer := "smtp.qq.com:587"// 邮件内容,确保包含 From 头部msg := []byte("From: Sender Name <" + from + ">\r\n" +"To: " + sendTo + "\r\n" +"Subject: " + subject + "\r\n" +"\r\n" +body + "\r\n")// 设置 PlainAuthauth := smtp.PlainAuth("", from, password, "smtp.qq.com")// 发送邮件err := smtp.SendMail(smtpServer, auth, from, []string{sendTo}, msg)if err != nil {return fmt.Errorf("发送失败: %v", err)}return nil
}func main() {err := SendEmail("193*******@qq.com", "古树林书法社团", "您的验证码为:123456,请勿泄露于他人!该验证码5分钟内有效!如非本人操作,请忽略此邮件!")if err != nil {fmt.Println(err)fmt.Printf("%T\n", err)return}fmt.Println("发送验证码成功")
}
还是报相同的错误,能够收到邮件,于是采用加密的465端口:
package mainimport ("crypto/tls""fmt""net/smtp"
)func SendEmail(sendTo string, subject string, body string) error {from := "193*******@qq.com"password := "dsfdfcf******" // 邮箱授权码smtpServer := "smtp.qq.com:465"// 设置 PlainAuthauth := smtp.PlainAuth("", from, password, "smtp.qq.com")// 创建 tls 配置tlsconfig := &tls.Config{InsecureSkipVerify: true,ServerName: "smtp.qq.com",}// 连接到 SMTP 服务器conn, err := tls.Dial("tcp", smtpServer, tlsconfig)if err != nil {return fmt.Errorf("TLS 连接失败: %v", err)}defer conn.Close()client, err := smtp.NewClient(conn, "smtp.qq.com")if err != nil {return fmt.Errorf("SMTP 客户端创建失败: %v", err)}defer client.Quit()// 使用 auth 进行认证if err = client.Auth(auth); err != nil {return fmt.Errorf("认证失败: %v", err)}// 设置发件人和收件人if err = client.Mail(from); err != nil {return fmt.Errorf("发件人设置失败: %v", err)}if err = client.Rcpt(sendTo); err != nil {return fmt.Errorf("收件人设置失败: %v", err)}// 写入邮件内容wc, err := client.Data()if err != nil {return fmt.Errorf("数据写入失败: %v", err)}defer wc.Close()msg := []byte("From: Sender Name <" + from + ">\r\n" +"To: " + sendTo + "\r\n" +"Subject: " + subject + "\r\n" +"\r\n" +body + "\r\n")_, err = wc.Write(msg)if err != nil {return fmt.Errorf("消息发送失败: %v", err)}return nil
}func main() {err := SendEmail("193*******@qq.com", "古树林书法社团", "您的验证码为:123456,请勿泄露于他人!该验证码5分钟内有效!如非本人操作,请忽略此邮件!")if err != nil {fmt.Println("发送验证码失败:", err)//打印错误类型fmt.Printf("%T\n", err)return}fmt.Println("发送验证码成功")
}
这次控制台显示“发送验证码成功”,报错消失。
相关文章:

解决使用Golang的email库发送qq邮件报错short response,错误类型为textproto.ProtocolError
问题阐述 使用email库发送QQ邮件,采用465端口: package mainimport ("fmt""net/smtp""github.com/jordan-wright/email" )func SendEmail(sendTo string, subject string, body string) (err error) {e : email.NewEmai…...

为什么说高级工程师研究的不仅是器件的稳态,模拟器件的开关过程
高级工程师研究器件的开关过程而不仅仅是稳态,主要有以下几个原因: 1. 动态性能优化:开关过程中的特性,如上升时间、下降时间、过冲、振铃等,直接影响系统的性能。了解和优化这些动态特性对于提高系统的速度、精度和稳…...

Matlab实现白鲸优化算法(BWO)求解路径规划问题
目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1内容介绍 白鲸优化算法(BWO)是一种受自然界白鲸捕食行为启发的新型优化算法,它通过模拟白鲸的群体捕猎策略和社会互动来探索问题的最优解。BWO因其强大的全局搜索能力和高效的局部搜索能…...
SQLserver索引的优化和使用
在SQL Server中,索引的优化和有效使用是提高查询性能的关键。以下是一些详细的步骤和最佳实践,帮助你优化和使用索引。 1. 理解索引类型 聚集索引(Clustered Index) 定义:表中数据的物理排序顺序与索引的逻辑顺序相…...

Linux 安装nacos
1.下载版本 https://github.com/alibaba/nacos/tags 2.解压压缩包,启动 (1)将压缩包放到/usr/local目录下,解压 tar -xvf nacos-server-2.0.0-BETA.tar.gz(2)删除压缩包 rm -f nacos-server-2.0.0-BETA.tar.gz(3) 找到nacos的mysql的数据库脚本,在数…...
水仙花判断
一个三位整数,如果满足条件:个位数的立方十位数立方百位数立方这个数,那么称之为“水仙花数” 编程判断一个三位整数是不是水仙花数。 输入格式: 输入一个三位整数 输出格式: 是则输出YES,不是输出 NO (注意是大写字母…...

在VS中安装chatGPT
2、在VSCode中打开插件窗口 3、输入ChatGPT 4、这里有个ChatGPT中文版,就它了 5、安装 6、这时候侧边栏多了一个chatGPT分页图标,点击它 7、打个招呼 8、好像不行 9、看一下细节描述 10、根据要求按下按下快捷键 Ctrl Shift P 11、切换成国内模式 12、…...

算法笔记:Day-09(初始动态规划)
509. 斐波那契数 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) 0,F(1) 1 F(n) F(n - 1) F(n - 2),其中 …...
“探索未来医疗:生成式人工智能在医疗领域的革命性应用“
生成式人工智能(GenAI)在医疗领域的应用具有巨大的潜力和变革性,以下是一些关键的应用领域: 医学影像分析: GenAI模型通过深度学习技术,能够自动识别医学影像中的病变区域,提高诊断的准确性和速…...

数字IC后端实现Innovus 时钟树综合(Clock Tree Synthesis)典型案例
对于如下所示电路,要求以下几路做到等长,clock skew控制在50ps以内,clock tree insertion delay做到800ps! from FF/Q to FF1_1/D through the FF1 CK from FF/Q to FF2_1/D through the FF2 CK from FF/Q to FF3_1/D through the FF3 CK fr…...
Matlab应用制作入门
要在 MATLAB 中创建一个简单的应用程序,你可以使用 App Designer,这是一个用于构建交互式应用的工具。以下是一个简单的步骤,帮助你创建一个基本的 MATLAB 应用程序: 1. 打开 App Designer 在 MATLAB 命令窗口中输入 appdesigne…...
什么是声明式编程什么是函数式编程,打比方说明
在前端开发中,声明式编程和函数式编程是两种不同的编程范式,各自有其特定的理念和用法。下面详细介绍这两种编程范式,并通过比喻进行说明。 声明式编程 定义: 声明式编程是一种编程风格,强调“你想要什么”而不是“怎…...
SpringBoot+Shiro权限管理
Shiro是一个强大的Java安全框架,提供了身份验证、授权、加密、会话管理以及与Web集成等多种安全功能。以下是对Shiro权限管理的详细总结: 一、Shiro权限管理的基本概念 权限管理,一般指根据系统设置的安全规则或者安全策略,用户…...
前端面试题22 | 什么是跨域问题?怎么解决?
哈喽小伙伴们大家好!新的一周开始啦~距离2024年结束也仅有两个月了,不知道大家年初给自己制定的目标实现了多少?不管怎样,接下来的两个月都请继续加油哦!我们坚持下来了,我们就是最棒的! 今天,继续来给大家分享一道面试题 在开发中,我们经常会遇到跨域的问题,尤其是开发前后…...

HarmonyOS Next星河版笔记--界面开发(3)
属性 1.1.设计资源-svg图标 需求:界面中展示图标→可以使用的svg图标(任意放大缩小不失真、可以改变颜色) 使用方式: ①设计师提供:基于项目的图标,拷贝到项目目录使用 Image($r(app.media.ic_dianpu)) .width(40) fillColor…...

科研绘图系列:R语言组合连线图和箱线图(linechart+boxplot)
文章目录 介绍加载R包数据数据预处理画图1画图2系统信息介绍 连线图(Line Chart)是一种常用的数据可视化图表,它通过将一系列数据点用直线段连接起来来展示数据随时间或有序类别变化的趋势。以下是连线图可以表示的一些内容: 时间序列数据:展示数据随时间变化的趋势,例如…...
对象的接口与设计模式在其中的作用
对象的接口 对象的接口定义了对象的行为和如何与外界进行交互。以下是对象接口的详细解释: 成员函数(Member Functions) 定义:成员函数是定义在类中的函数,用于实现类的行为。成员函数可以通过对象来调用࿰…...

如何自学机器学习?
自学机器学习可以按照以下步骤进行: 一、基础知识准备 数学基础: 高等数学:学习微积分(包括导数、微分、积分等)、极限、级数等基本概念。这些知识是后续学习算法和优化方法的基础。 线性代数:掌握矩阵…...

python中应该使用while 1吗?按位运算符可以代替逻辑运算符使用吗?
while 1 很多初学者都很喜欢使用while 1,原因可能是,1只需要输入一个字符,更加“省事”,可以“偷懒”,并且,1看起来更加简洁明了。 实际上,在python中,while 1与while True是等价的…...

线程ID和线程库
在linux中,线程的运行可以用lwp来标识,只是操作系统的标识方法,lwp表示轻量级进程,在Linux中,进程和线程都可以用lwp来标识,而对于用户来说,也有对应的线程ID, 线程库 在linux中&a…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...