背景

我们常使用邮件客户端,如 Foxmail 、Outlook 等收发邮件。大家应该了解邮件协议基础知识吧,发送邮件是通过 SMTP 协议完成,收取邮件则走的是 POP3 协议。由于工作原因,笔者曾对邮件协议的通信过程进行过完整的分析,这里整理下邮件协议的通信过程,以巩固对通信协议的理解。

协议是什么

我曾经做过一个基于 UDP 字节序列的应用:两个进程【一个用 Java 开发,另一个 是C++ 进程】之间,通过逐个解析 UDP 数据包中的字节数据完成通信业务,最小业务数据单位是比特。

大概的流程是这样子的:

  1. 循环读取 UDP 数据包
  2. 先取出第一个字节
  3. 再读取这个字节的前 2 个 bit 数据,它代表某一种业务类型
  4. 紧接着的 6 比特代表业务数据总长度
  5. 再循环读取第二个字节以后的数据,直到达到总长度

很多年过去了,已经忘记了那个应用的具体功能,但是对 UDP 字节数据的解析流程依然清晰。它让我理解了什么是协议,这其实就是一种基于简单处理规则的通信协议,也算是一种自定义的应用层协议了吧。

由此推及到 OSI 七层模型中的其他协议,它们跟这种简单约定类似,只不过通信规则更复杂一些!

SMTP 协议基础

SMTP 全称为「 Simple Mail Transfer Protocol 」,这是来自百度百科的解释:

先来了解一下 SMTP 的状态码和命令集:
3 分钟带你了解一封邮件的发送过程-LMLPHP
接着,我们来看看对 Foxmail 发送邮件的抓包分析。报文中,包含状态码的是邮件服务器响应的内容,命令则是客户端发起的。

认证

一个 SMTP 通信是由客户端发起连接邮件服务器开始的,这是我截取到的解析后的通信内容:
3 分钟带你了解一封邮件的发送过程-LMLPHP
这里用到的关键命令是 EHLOAUTH LOGIN,用来发起会话和身份认证, 客户端连接上服务器后的通信过程为:

  1. 服务器回复 220 状态码,告知客户端它已经准就绪;
  2. 客户端发送 EHLO 命令;
  3. 服务器回复 250 ,表示欢迎;
  4. 服务器又回复一堆 250(对应中间那几步);
  5. 客户端发起 AUTH LOGIN 身份认证;
  6. 服务器回应 334 等待客户发送认证信息;
  7. 客户端发送认证信息的密文数据,如此两次密文通信;
  8. 服务器回复 235 认证成功,身份认证流程完成。

准备

身份认证成功后,客户端向服务器端发送发件箱、所有收件箱地址,服务器验证无误后回复 250 OK。
3 分钟带你了解一封邮件的发送过程-LMLPHP

数据发送

3 分钟带你了解一封邮件的发送过程-LMLPHP
邮件正文发送的过程:

  1. 客户端发送 DATA 命令;
  2. 服务端回复 354 状态码,告知客户端可以发送邮件内容;
  3. 客户端开始发送邮件正文;
  4. 服务器端回复 250 ;
  5. 客户端发送 QUIT 命令结束会话;
  6. 服务器回复 221,告诉客户端它正在关闭传输通道。

总结

以上就是一封邮件所经历的完整过程,像是客户端和服务器隔空喊话一样,每一步都有问有答、井然有序。这么看一遍,发现还是通信协议还是蛮有意思的,这大概是应用层协议的一般思路吧,定义业务规则和状态码,按照双方约定好的流程进行通话。

理解这个过程后,如果工作中碰到需要进行通信的时候,可以参考网络协议的设计思路,实现基于 Socket 的通信业务应该是不复杂的!

08-16 07:35