SMTP 基本工作过程 — 命令-应答交互
1 TCP 连接建立与服务器问候
SMTP 客户(发送方)与 SMTP 服务器(接收方)通过 TCP 端口 25 建立连接。
220 smtp.example.com ESMTP Service Ready
连接建立后,服务器主动推送"服务就绪"应答(代码 220),表示准备好接收 SMTP 命令。
SMTP 中使用三位数字应答码:2xx 成功,3xx 中间应答,4xx 临时失败,5xx 永久失败。
SMTP 交互模式
SMTP 的基本模式是:
客户发送命令 → 服务器返回应答
每条命令以 <CRLF> 结尾。
每条应答以三位数字开头,后跟描述文本。
SMTP 使用 TCP(不是 UDP),因为有大量邮件内容和命令需要可靠传输。
2 身份声明、发件人与收件人
250 smtp.example.com Hello mail.example.com
—— 客户表明身份 ——
MAIL FROM: <sender@example.com>
250 2.1.0 Sender OK
—— 告知邮件来自谁 ——
RCPT TO: <receiver@example.org>
250 2.1.5 Recipient OK
—— 告知邮件发给谁 ——
| 命令 | 含义 | 成功应答 |
HELO 域名 | 客户告知自己的域名 | 250 |
MAIL FROM: <地址> | 告知发件人邮箱地址 | 250 |
RCPT TO: <地址> | 告知收件人邮箱地址 | 250(存在)或 550(不存在) |
注意 MAIL FROM 和 RCPT TO 是 SMTP 命令中指定的信封地址,可能与邮件首部中的 From: 和 To: 不一致。
3 DATA 命令——传送邮件内容
354 Start mail input; end with <CRLF>.<CRLF>
—— 服务器准备好接收邮件内容 ——
From: sender@example.com
To: receiver@example.org
Subject: Test Email
Hello, this is a test message.
.
250 2.6.0 Message accepted for delivery
—— 邮件内容结束,服务器确认接收 ——
DATA 命令的关键细节
1. 服务器应答 354 表示准备接收。
2. 客户发送邮件内容(包含首部和主体)。
3. 邮件内容以 <CRLF>.<CRLF> 结束(单独一行的句点)。
4. 服务器收到结束符后回复 250。
<CRLF>.<CRLF>(回车换行 + 句点 + 回车换行)是 SMTP 的邮件结束标记。如果邮件正文中含有单独一行的句点,发送方必须额外加一个句点(变为 ..)进行转义。
4 QUIT 命令——释放连接
221 smtp.example.com Service closing transmission channel
[TCP 连接关闭]
客户发送 QUIT 命令后,服务器回复 221 并主动关闭 TCP 连接。至此,一次 SMTP 会话结束。
如果还有下一封邮件需要发送,客户需要重新建立 TCP 连接并开始新的 SMTP 会话。
| 事件 | 应答码 | 含义 |
| 连接建立 | 220 | 服务就绪 |
| HELO 成功 | 250 | 请求动作完成 |
| MAIL FROM 成功 | 250 | 发件人 OK |
| RCPT TO 成功 | 250 | 收件人 OK |
| DATA 准备接收 | 354 | 开始邮件输入 |
| 邮件接收成功 | 250 | 邮件已接受 |
| QUIT 成功 | 221 | 服务关闭 |
| 错误:服务不可用 | 421 | 稍后重试 |
| 错误:邮箱不存在 | 550 | 永久失败 |
★ SMTP 会话完整过程一览
220 smtp.example.com ESMTP Service Ready
===== 身份与信封 =====
HELO client.example.com
250 smtp.example.com
MAIL FROM: <alice@example.com>
250 2.1.0 Sender OK
RCPT TO: <bob@example.org>
250 2.1.5 Recipient OK
===== 邮件内容 =====
DATA
354 Start mail input
[邮件首部 + 主体 + <CRLF>.<CRLF>]
250 2.6.0 Message accepted
===== 释放连接 =====
QUIT
221 Service closing
===== TCP 连接关闭 =====
记住顺序:HELO → MAIL FROM → RCPT TO → DATA(含结束符)→ QUIT。每一步都有对应的服务器应答码。