电子邮件发送接收原理(附 go 语言实现发送邮件)

news2024/9/20 16:59:14

前言

首先要了解电子邮件的发送接收,不是点到点的。我想给你传达个消息,不是直接我跑到你家里喊你:“嘿,xxx,是你的益达,快拿走”。

而是类似快递的发送收取方式,是有服务器的中转的。我先将我的益达给快递公司,然后快递公司将货运到代收点,通知你去取快递。

题外话:一开始的邮件传递就是点到点的模式,因为最开始的计算机都是大型主机,并且 24 小时不停机,用户也是实时在线,而且每台主机都有固定的 IP 地址。

电子邮件发送接收原理

下图是 邮件发送的基本过程与概念 这篇文章的图,感觉很清晰,直接拿过来用了。

在这里插入图片描述

该图表示的是用户 AQQ邮箱 发送邮件到用户 B163邮箱

步骤说明:

  1. 用户 A 的电子邮箱为:xx@qq.com,通过邮件客户端软件写好一封邮件,交到 QQ 的邮件服务器,这一步使用的协议是 SMTP,对应图示的 ①;
  2. QQ 邮箱会根据用户 A 发送的邮件进行解析,也就是根据收件地址判断是否是自己管辖的账户,如果收件地址也是 QQ 邮箱,那么会直接存放到自己的存储空间。这里我们假设收件地址不是 QQ 邮箱,而是 163 邮箱,那么 QQ 邮箱就会将邮件转发到 163 邮箱服务器,转发使用的协议也是 SMTP,对应图示的 ②;
  3. 163 邮箱服务器接收到 QQ 邮箱转发过来的邮件,也会判断收件地址是否是自己,发现是自己的账户,那么就会将 QQ 邮箱转发过来的邮件存放到自己的内部存储空间,对应图示的 ③;
  4. 用户 A 将邮件发送了之后,就会通知用户 B 去指定的邮箱收取邮件。用户 B 会通过邮件客户端软件先向 163 邮箱服务器请求,要求收取自己的邮件,对应图示的 ④;
  5. 163 邮箱服务器收到用户 B 的请求后,会从自己的存储空间中取出 B 未收取的邮件,对应图示 ⑤;
  6. 163 邮箱服务器取出用户 B 未收取的邮件后,将邮件发给用户 B,对应图示的 ⑥;最后三步用户 B 收取邮件的过程,使用的协议是 POP3;

邮件服务器

由于搭建自己的邮箱服务,需要有自己的服务器,大多数情况下个人是没有的,这里用 QQ 邮箱进行测试。


打开 QQ 邮箱网站 -> 登录 -> 设置 -> 账号 ->【POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV 服务】 设置为开启 —> 此时需要手机发送信息进行验证,验证成功后会获得授权码 -> 设置完成后,保存更改

操作完成后,服务状态如下即可

在这里插入图片描述

注意: 授权码要自己保存好,连接邮件服务器的时候用的就是这个。

发送邮件 go 代码

借助第三方开源库 go-simple-mail,下方是简单的发送邮件的测试代码:

package main

import (
	"log"
	"github.com/xhit/go-simple-mail/v2"
)

func main() {
	server := mail.NewSMTPClient()
    server.Host = "smtp.qq.com" // qq 邮件服务地址
	server.Port = 25
	server.Username = "xxx@qq.com"
	server.Password = "授权码"
    server.Encryption = mail.EncryptionTLS

    smtpClient, err := server.Connect()
    if err != nil {
        log.Fatal(err)
    }

    // Create email
    email := mail.NewMSG()
    email.SetFrom("发件人昵称<xxx@qq.com>")
    email.AddTo("收件人邮箱")
    email.SetSubject("测试主题")

    str := `我是测试内容`
    email.SetBody(mail.TextPlain, str)  //发送信息 
    email.AddAttachment("附件地址") // 附件

    // Send email
    err = email.Send(smtpClient)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("发送成功")
}

代码不复杂,如果有其他的需求,可以查看官方文档,其中例子也很多,自行查看。

总结

本文主要介绍了电子邮件发送接收的原理,邮件传输过程中还有许多细节,如:DNS 解析、邮件协议等都没有详细阐述。

大体流程:用户 A -> 邮箱服务器 (-> 其他邮箱服务器) -> 用户 B

最后介绍了下使用 golang 来发送邮件,配置好服务器后还是很方便的。

参考

  • go-simple-mail
  • 邮件发送的基本过程与概念
  • 邮件原理你真的造吗

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

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

相关文章

1个月5次发版:测试人的模块测试策略分类归纳

笔者所在项目经历了一个月开发周期&#xff0c;该项目有5名开发人员&#xff0c;1名项目经理&#xff0c;1名测试人员&#xff0c;涵盖OA系统8个模块&#xff0c;在短短1个月中进行了5次发布。 现进行模块测试策略分类归纳。 已有模块 配置项优化 对于已有模块的配置项优化&…

【Python】collections.Counter

Python内置模块collections中的Counter是字典子类。Counter不是字典&#xff0c;但很像字典。 Counter具有字典的键和值&#xff0c;键是各个元素&#xff0c;值为该元素出现的次数。 Counter相当于计数器。常用于哈希映射&#xff08;哈希表&#xff09;。 from collection…

Unity Inspector编辑器扩展,枚举显示中文,枚举值自定义显示内容

记录&#xff01;Unity Inspector面板编辑器扩展&#xff0c;枚举显示中文&#xff0c;枚举值自定义显示内容&#xff0c;显示部分选项。效果如下&#xff1a; 枚举类代码&#xff1a; using System.Collections; using System.Collections.Generic; using UnityEngine;public…

从顺序表表中删除具有最小值的元素(假设不唯一)并由函数返回被删元素值

从顺序表表中删除具有最小值的元素&#xff08;假设不唯一&#xff09;&#xff0c;并由函数返回被删元素值 空出的位置由最后一个元素填补&#xff0c;若顺序表为空&#xff0c;则显示出错误信息并退出运行 //顺序表定义及初始化 #define _CRT_SECURE_NO_WARNINGS #include&l…

SpringMVC Day 01:入门案例

前言 在我们的日常工作和学习中&#xff0c;Web 开发是一个无法回避的重要环节。而在 Java Web 开发领域&#xff0c;SpringMVC 无疑是一个重量级选手。它以其灵活性、强大功能和清晰的 MVC 结构&#xff0c;赢得了大量开发者的青睐。但是&#xff0c;对于初学者来说&#xff…

云表:【建议收藏】什么是低代码?一分钟掌握低代码开发

IT圈的风口总是轮番上演&#xff0c;但只有在浪潮退去后&#xff0c;真正具有社会价值的产品才能脱颖而出。同样地&#xff0c;这个规则也适用于“低代码”这个赛道。 云表平台认为&#xff0c;低代码将成为未来企业数字化转型中不可或缺的重要元素之一。随着市场竞争的不断加剧…

Qt 窗口的尺寸

本文通过多个案例&#xff0c;详细说明关于Qt窗体尺寸的一些重要问题 默认尺寸 对于一个Qt的窗口&#xff08;继承于QWidget&#xff09;&#xff0c;获取其窗体尺寸的方法size()&#xff1b; 以一个Qt创建Qt Widgets Application项目的默认生成代码为基础&#xff0c;做如下…

安科瑞电能计量管理系统

安科瑞 崔丽洁 随着国家电网改革政策的逐步推进和落实&#xff0c;Acrel-3000WEB电能管理解决方案运用互联网和大数据技术&#xff0c;为电力运维公司提供电能管理解决方案。该平台作为连接运维单位和用电企业的纽带&#xff0c;全方面监视用户配电系统的运行状态和电量数据&am…

分享一款基于 AI 的 Chrome 插件

最近使用大模型比较多&#xff0c;公司虽然提供了免费的 ChatGPT 但是需要跳转特定页面才能访问&#xff0c;比较麻烦&#xff0c;于是就想到是否可以开发一款类似于有道词典一样的 Chrome 插件&#xff0c;可以在任意页面使用&#xff0c;虽然市面上也有类似的插件&#xff0c…

2023中国物流系统集成商百强榜研究报告(附下载)

随着智能物流建设的不断深入&#xff0c;企业应用了越来越多的自动化、智能化物流设备与管理软件。但各物流功能之间的效益背反问题如何解决? 各品牌与类型物流设备的接口各异如何统一调度? 各物流设备与管理软件之间的数据如联通传输? 乃至物流设备与生产设备、物流管理软…

如何新建一个一台交换机下连两个PC的拓扑

文章目录 1.效果如下1.新建一个空白拓扑页选择设备类型向工作区添加设备如何选择链接线如何使设备之间链接上启动设备 1.效果如下 1.新建一个空白拓扑页 选择设备类型 向工作区添加设备 如何选择链接线 如何使设备之间链接上 同理右侧设备也是这样链接的 启动设备 同理PC1和P…

nohup命令后台启动jar包

使用jps命令查看后台启动的进程 kill -9 218729 杀掉进程&#xff0c;如果没有启动过就不用了&#xff0c;忘了的话就会有两个jar的进程&#xff0c;都杀掉然后重新启动jar包然后进入到jar包对应的目录下使用nohup命令启动jar包 命令&#xff1a;nohup java -jar xxx.jar >c…

轻量级仿 SpringBoot=嵌入式 Tomcat+SpringMVC

SpringBoot 嵌入了 Web 容器如 Tomcat/Jetty/Undertow&#xff0c;——这是怎么做到的&#xff1f;我们以 Tomcat 为例子&#xff0c;尝试调用嵌入式 Tomcat。 为了说明如何打造轻量级的 SpringBoot&#xff0c;本文分为“嵌入式 Tomcat”、“增强 SpringMVC”和“打包/部署”…

LDO基础知识

LDO基础知识 线性稳压器基本上由输入IN、输出OUT、GND引脚所构成 可变线性稳压器则在输出增加输出电压的反馈&#xff08;feed back&#xff09;引脚 (通过分压电阻来进行调节输出电压的大小) LDO 线性稳压器内部电路如下图所示。 基本上由误差放大器&#xff08;误差检测用…

行情分析——加密货币市场大盘走势(10.25)

目前大饼继续上涨&#xff0c;还没有看到震荡盘整的迹象。从MACD日线来看&#xff0c;连续绿色实心柱已经10天。现在有点上涨无力了&#xff0c;而现在入场做空性价比更高&#xff0c;看反弹到33000-32000。如果谨慎点&#xff0c;可以继续等待。 以太目前来看和大饼一样那个也…

MySQL中的Base64函数

编码函数to_base64() select to_base64("123") 解码函数from_base64() select from_base64("MTIz")

leetcode:1662. 检查两个字符串数组是否相等(python3解法)

难度&#xff1a;简单 给你两个字符串数组 word1 和 word2 。如果两个数组表示的字符串相同&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 数组表示的字符串 是由数组中的所有元素 按顺序 连接形成的字符串。 示例 1&#xff1a; 输入&#xff1a;word1 […

AMS启动流程

本文均采用Android 14代码进行讲解&#xff0c;学习可以使用以下地址&#xff1a;Search 一、AMS启动流程 AMS的启动是在SyetemServer进程中启动的&#xff0c;从SyetemServer的main方法开始进入&#xff1a; 1.SystemServer.java main(String[] args) /*** The main entr…

Qt篇——子控件QLayoutItem与实际控件的强转

方法&#xff1a;使用qobject_cast<QLabel*>() &#xff0c;将通过itemAt(i)获取到的子控件(QLayoutItem)强转为子控件的实际类型(如QLineEdit、QLabel等)。 场景举例&#xff1a; QLabel *label qobject_cast<QLabel*>(ui->horizontalLayout_40->itemAt(0…

c#使用ExifLib库提取图像的相机型号、光圈、快门、iso、曝光时间、焦距信息等EXIF信息

近期公司组织了书画摄影比赛&#xff0c;本人作为摄影爱好者&#xff0c;平时也会拍些照片&#xff0c;这次比赛当然不能错过。为了提高获奖概率&#xff0c;选了19张图像作为参赛作品。但是&#xff0c;摄影作品要提交图像的光圈、曝光时间等参数。一两张还可以通过电脑自带软…