POP3 — 邮局协议第三版
邮件的『下载』协议:应用层,基于 TCP 110(POP3S 995),由 RFC 1939 定义,取回后通常删除服务端副本
Table of Contents
1. 协议定位
| 项目 | 信息 |
|---|---|
| 所属层 | 应用层(Application Layer) |
| 英文全称 | Post Office Protocol - Version 3(邮局协议第三版) |
| 主要 RFC | RFC 1939(POP3 主标准,STD 53);RFC 2449(扩展机制 CAPA);RFC 2595(STLS,即 POP3 over TLS);RFC 5034(SASL AUTH);RFC 8314(隐式 TLS 995 推荐) |
| 端口 | TCP 110(明文 / STLS 升级)、TCP 995(POP3S,隐式 TLS) |
| 封装于 | TCP,文本行式命令,行结束符 CRLF |
| 典型应用 | 单设备离线收信;把邮件"搬"到本地长期归档;低带宽/低资源环境(嵌入式、脚本自动化) |
2. 一句话理解
POP3 把服务器当成一个"临时信箱":进去、把信全部搬走、(默认)清空信箱、走人——之后所有阅读、分类、检索都在本地完成。
生活化类比
POP3 就像小区楼下的信报箱:你拿钥匙打开,把里面的信一封不落地全塞进自己包里,然后把信箱清空、锁上门走人。
从此这些信只在你家里,你随时可以翻看、整理、归档,但邻居(你的另一台设备)再去开那个信箱,就什么都看不到了。这就是为什么手机用 POP3 收过的信,电脑上再收就没了。
3. 它解决什么问题
为什么没有它,网络就"缺了一块":
在拨号上网时代,用户按分钟计费、无法长时间在线,需要一个极简、快速、把邮件搬到本地就断线的取信方式。POP3 因此被设计得非常克制:
- 取信:SMTP 只负责把邮件送到收件服务器的邮箱,用户主机(尤其是不常在线的 PC)无法作为 SMTP 目标,必须有一个"主动去拉"的协议。
- 极简:命令不到 15 条,响应只有
+OK/-ERR两种,实现代价极低,几十行代码就能写一个能用的 POP3 客户端。 - 离线可用:邮件下载到本地后,断网也能随时阅读、搜索、归档,不依赖服务器。
4. 核心特征
- 【三状态机】:
AUTHORIZATION(认证)→TRANSACTION(事务)→UPDATE(更新提交)。删除操作在 TRANSACTION 阶段只是打标记,真正生效在 QUIT 触发的 UPDATE 阶段。 - 【响应极简】:
+OK表示成功,-ERR表示失败,无细分状态码——这也意味着排错信息全靠后面那句自由文本。 - 【只有一个邮箱】:POP3 只操作 INBOX,不支持服务器端文件夹,也没有"已读/未读/星标"等标志的服务端概念。
- 【默认下载即删除】:客户端可配置"在服务器保留副本"(靠
UIDL记录已下载编号并跳过DELE),但这是客户端行为,不是协议特性。 - 【邮件序号会变】:会话内邮件按 1..N 编号,下次连接编号可能全变;跨会话唯一标识必须用
UIDL返回的 UID。 - 【独占锁定】:会话期间服务器对邮箱加排他锁,同一账号第二个 POP3 连接通常会被拒(
-ERR mailbox in use)。
5. 与其他协议的关系
| 相关协议 | 关系 |
|---|---|
| SMTP | 上游:SMTP 把信送进邮箱,POP3 才有信可取;两者共同构成一次完整收发 |
| IMAP | 同类竞品:POP3 是"下载搬走",IMAP 是"在线管理",多设备场景 IMAP 全面胜出 |
| TCP | 承载层 |
| TLS | 通过 STLS(110 升级)或隐式 TLS(995)加密;否则 USER/PASS 明文过网 |
| DNS | 客户端解析邮件服务器主机名(如 pop.qq.com)时使用 |
6. 本目录学习路线
- 01-原理与报文 — 三状态机模型、完整命令集与多行响应格式、UIDL 与"保留副本"实现、会话时序图。
- 02-实战与排错 — Wireshark 过滤、telnet/openssl 手工收信、邮箱锁定与重复收信故障、与 IMAP 对比速查、面试题。
学习建议:POP3 是所有应用层协议里最容易手工完整跑通的一个,强烈建议用
openssl s_client -connect pop.qq.com:995亲手敲一遍USER → PASS → LIST → RETR 1 → QUIT,二十分钟就能彻底掌握。初学者最常踩的坑:以为
DELE一发出邮件就没了。其实DELE只是打个标记,必须发出QUIT进入 UPDATE 阶段才真正删除;中途异常断线,所有删除标记全部作废,邮件下次还会被重新下载。另一个坑是拿会话内的邮件序号当唯一 ID 用——序号下次连接就可能全变,跨会话去重只能靠UIDL。