← RFC Reference

RFC 2920 – SMTP 流水线处理

Internet Standard (STD 60) Core SMTP & Message Format Published March 2026
ELI5: 普通 SMTP 就像一场对话,你说一句话,等对方回应,然后再说下一句。管道化就像连串说出几句话,让对方一次性回应所有内容。你不必在每个命令之间暂停,所以整个对话完成得快得多——尤其是当双方距离很远的时候。

为什么这个RFC存在

标准SMTP是严格的请求-响应协议。客户端发送一个命令,等待服务器响应,然后发送下一个。每个往返都会增加延迟,特别是在高延迟网络链路上。对于有50个收件人的消息,客户端仅针对RCPT TO命令就需要50个独立的往返。

RFC 2920定义了PIPELINING SMTP扩展,允许客户端批量发送多个命令而无需等待单个响应。服务器缓冲并按顺序处理这些命令,然后发送所有响应。这可以大幅减少SMTP会话的总时间。

管道化是最广泛支持的SMTP扩展之一。几乎每个现代邮件服务器都会宣告它,大多数SMTP客户端库默认使用它。

工作原理

  1. 客户端发送EHLO并确认服务器在其功能列表中宣告PIPELINING。
  2. 客户端将安全管道化的命令分组在一起——通常是MAIL FROM、一个或多个RCPT TO和DATA。
  3. 客户端快速连续发送所有这些命令,无需等待单个回复。
  4. 服务器按顺序处理每个命令并按顺序为每个命令发送一个响应。
  5. 客户端读取所有响应并处理任何错误(例如被拒绝的收件人)。

SMTP示例

不使用管道化(信封需要5个往返):

C: MAIL FROM:<news@example.com> S: 250 2.1.0 OK C: RCPT TO:<alice@recipient.com> S: 250 2.1.5 OK C: RCPT TO:<bob@recipient.com> S: 250 2.1.5 OK C: RCPT TO:<carol@recipient.com> S: 550 5.1.1 User unknown C: DATA S: 354 Start mail input

使用管道化(整个信封需要1个往返):

# 客户端一次发送所有信封命令 C: MAIL FROM:<news@example.com> C: RCPT TO:<alice@recipient.com> C: RCPT TO:<bob@recipient.com> C: RCPT TO:<carol@recipient.com> C: DATA # 服务器按顺序响应所有五个命令 S: 250 2.1.0 OK S: 250 2.1.5 OK S: 250 2.1.5 OK S: 550 5.1.1 User unknown S: 354 Start mail input # 客户端发送消息内容(carol被拒绝,但alice和bob继续) C: Subject: Weekly update C: C: This week's news... C: . S: 250 2.0.0 OK, queued

关键技术细节

哪些命令可以管道化

并非所有SMTP命令都安全可管道化。RFC 2920将命令分为两类:

安全可管道化 必须等待响应
MAIL FROM EHLO / HELO
RCPT TO STARTTLS
DATA AUTH
RSET QUIT
NOOP DATA内容(点转义的正文)

改变连接状态的命令(EHLO、STARTTLS、AUTH)是同步点——客户端必须等待响应才能发送任何其他内容。

错误处理

使用管道化时,批处理中的某些命令可能成功,而其他命令可能失败。客户端必须按顺序将响应与命令匹配。被拒绝的RCPT TO不会使整个事务失效——消息仍会传递给已接受的收件人。但是,如果MAIL FROM被拒绝,后续RCPT TO命令也会失败。

TCP缓冲考虑

管道化依赖于TCP的缓冲。客户端将多个命令写入套接字而不读取,相信TCP发送缓冲区可以容纳它们。对于非常大批量的RCPT TO命令(数百或数千个),客户端可能需要分组管道化以避免填满TCP缓冲区和死锁。

与STARTTLS的交互

在包含STARTTLS的EHLO响应之后,客户端不得将STARTTLS与其他命令管道化。TLS握手改变整个连接的状态,所以它是硬同步点。建立TLS后并发送新EHLO时,管道化可以恢复。

常见错误

可传递性影响

Related RFCs