NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
SMTP

SMTP协议实现 更多...

struct  smtp_message
 SMTP邮件消息结构 更多...
class  smtp_socket
 SMTP Socket类 更多...

详细描述

SMTP协议实现

支持明文、STARTTLS和隐式TLS连接与多种认证方式。

遵循的国际标准

本实现严格遵循以下电子邮件传输与安全相关标准规范:

SMTP 核心协议规范:

SMTP 扩展标准:

SMTP 安全标准:

SMTP 认证标准:

邮件格式与 MIME 标准:

SMTP 会话流程

根据 RFC 5321 §3.1,SMTP 会话的基本流程:

步骤 客户端命令 服务器响应码 说明
1 - 220 服务器就绪
2 EHLO domain 250 扩展问候(ESMTP)
3 STARTTLS 220 升级到 TLS(可选)
4 AUTH LOGIN 334/235 认证(可选)
5 MAIL FROM: 250 设置发件人
6 RCPT TO: 250 设置收件人(可多次)
7 DATA 354 开始发送邮件正文
8 . 250 邮件正文结束
9 QUIT 221 断开连接

SMTP 响应码分类

根据 RFC 5321 §4.2,SMTP 响应码按百位数字分类:

类别 响应码范围 含义 典型响应码
2xx 200 – 299 命令成功 220 (就绪), 250 (OK), 235 (认证成功)
3xx 300 – 399 命令待处理 334 (等待认证凭据), 354 (开始数据)
4xx 400 – 499 临时失败(可重试) 450 (邮箱不可用)
5xx 500 – 599 永久失败 550 (邮箱不存在), 554 (事务失败)

TLS 连接模式

根据 RFC 3207 和 RFC 8314,SMTP 支持三种 TLS 模式:

模式 TLS 时机 端口 安全性
none 不加密 25 最低(明文传输)
starttls 先明文,后升级 587 中等(存在降级攻击风险)
implicit 连接即 TLS 465 最高(始终加密)

SMTP 认证方式

根据 RFC 4954,本实现支持以下认证方式:

方式 RFC 引用 说明
none - 无认证
plain RFC 4616 用户名和密码 Base64 编码传输(需 TLS)
login RFC 4954 用户名和密码分两步 Base64 编码传输(需 TLS)

邮件格式说明

根据 RFC 5322 和 RFC 2045,邮件格式规范:

**邮件头字段**:

字段 RFC 引用 说明 是否必需
From §3.4 发件人地址
To §3.4 收件人地址
Cc §3.4 抄送地址
Bcc §3.4 密送地址(不显示)
Subject §3.6.5 邮件主题
Date §3.6.1 发送日期 否(自动生成)
Content-Type RFC 2045 内容类型(text/plain 或 text/html)
MIME-Version RFC 2045 MIME 版本(固定 1.0)

**正文编码规则**:

  • \r\n.\r\n 作为邮件正文结束标记
  • 正文中以 . 开头的行需要额外转义一个 .
  • Bcc 收件人不在邮件头中显示,但同样通过 RCPT TO 发送

使用示例

基本 SMTP 连接与邮件发送:

// 连接到 SMTP 服务器(IP 地址)
auto addr = ip_address::parse("192.168.1.100", ports::smtp);
smtp.connect(*addr, "example.com", smtp_socket::tls_mode::none);
// 构建邮件
msg.from = "sender@example.com";
msg.to = {"recipient@example.com"};
msg.subject = "Test Email";
msg.body = "Hello, this is a test email!";
// 发送邮件
smtp.send(msg);
smtp.disconnect();
static optional< ip_address > parse(const string &host, ports port=ports{}) noexcept
从字符串解析IP地址
SMTP Socket类
void disconnect()
断开连接,发送QUIT命令
void send(const smtp_message &msg)
发送邮件
void connect(const ip_address &addr, const string &domain="localhost", tls_mode mode=tls_mode::none, const ssl_context *ctx=nullptr, const string &sni_hostname="")
连接SMTP服务器(IP)
SMTP邮件消息结构
string body
邮件正文
string subject
邮件主题
string from
发件人地址
vector< string > to
收件人地址列表

使用 STARTTLS 和认证:

ctx.load_verify_locations("ca-bundle.crt");
smtp.connect("smtp.qq.com", 587, "example.com",
smtp.authenticate("username@qq.com", "password",
msg.from = "sender@qq.com";
msg.to = {"recipient@example.com"};
msg.subject = "Encrypted Email";
msg.body = "<h1>Hello</h1><p>This is HTML email.</p>";
msg.is_html = true;
smtp.send(msg);
smtp.disconnect();
void authenticate(const string &username, const string &password, auth_method method=auth_method::plain)
SMTP认证
@ starttls
STARTTLS(从明文升级到TLS)
SSL/TLS上下文管理类
@ TLS_CLIENT
TLS客户端端
bool is_html
是否为HTML格式
注解
SMTP 协议使用 TCP 端口 25(明文)、587(STARTTLS)或 465(隐式 TLS)。 现代邮件服务推荐使用 STARTTLS(端口 587)或隐式 TLS(端口 465)。
警告
明文 SMTP 传输的所有数据都是可见的, 仅应在受控网络环境中使用。生产环境强烈建议使用 STARTTLS 或隐式 TLS。 PLAIN/LOGIN 认证方式在无 TLS 保护时等同于明文密码传输。
参见
https://www.rfc-editor.org/rfc/rfc5321.html
https://www.rfc-editor.org/rfc/rfc3207.html
https://www.rfc-editor.org/rfc/rfc4954.html
https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol