2.3 互联网中的电子邮件#

2.3 Electronic Mail in the Internet

电子邮件自互联网诞生之初便已存在。它在互联网早期是最流行的应用 [Segaller 1998],并在这些年中变得更加复杂和强大。它仍然是互联网中最重要和最常用的应用之一。

与普通邮政邮件类似,电子邮件是一种异步通信媒介 —— 人们可以在方便的时候发送和阅读消息,无需与他人的时间安排协调。与邮政邮件相比,电子邮件传输快速、易于分发且成本低廉。现代电子邮件拥有许多强大功能,包括带附件的消息、超链接、HTML 格式文本和嵌入图片等。

本节我们将研究构成互联网电子邮件核心的应用层协议。但在深入讨论这些协议之前,先从更高层次了解互联网邮件系统及其关键组件。

图 2.14 展示了互联网邮件系统的高层视图。从图中可见,该系统包含三个主要组件: 用户代理(user agents)邮件服务器(mail servers)简单邮件传输协议(SMTP)

我们将在发送者 Alice 向接收者 Bob 发送电子邮件的场景中描述这些组件。用户代理允许用户读取、回复、转发、保存和撰写消息。Microsoft Outlook 和 Apple Mail 是电子邮件用户代理的例子。当 Alice 撰写完她的邮件后,她的用户代理将邮件发送到她的邮件服务器,邮件被放入该服务器的外发邮件队列中。当 Bob 想要阅读邮件时,他的用户代理会从其邮件服务器的邮箱中提取邮件。

邮件服务器构成电子邮件基础设施的核心。每位接收者,例如 Bob,在某个邮件服务器中都有一个 邮箱(mailbox)。Bob 的邮箱管理并维护发送给他的邮件。通常一封邮件从发送者的用户代理开始,传送到发送者的邮件服务器,再传送到接收者的邮件服务器,最后投递到接收者的邮箱中。当 Bob 想访问邮箱中的邮件时,包含其邮箱的邮件服务器会对其进行身份验证(通过用户名和密码)。Alice 的邮件服务器还必须处理 Bob 的邮件服务器出现故障的情况。如果 Alice 的服务器无法向 Bob 的服务器投递邮件,它会将邮件保存在一个 消息队列(message queue) 中,并尝试稍后再次发送。通常每隔 30 分钟重试一次;如果几天内仍未成功,服务器会删除该邮件,并通过电子邮件通知发件人(Alice)。

../_images/150-0.png

图 2.14 互联网邮件系统的高层视图

SMTP 是互联网电子邮件的主要应用层协议。它使用 TCP 提供的可靠数据传输服务将邮件从发送方邮件服务器传送到接收方邮件服务器。与大多数应用层协议类似,SMTP 包含两个部分:在发送方邮件服务器上运行的客户端部分,以及在接收方邮件服务器上运行的服务器部分。每个邮件服务器都运行 SMTP 的客户端和服务器两部分。当邮件服务器向其他邮件服务器发送邮件时,它充当 SMTP 客户端;当从其他邮件服务器接收邮件时,它充当 SMTP 服务器。

原文

Electronic mail has been around since the beginning of the Internet. It was the most popular application when the Internet was in its infancy [Segaller 1998] , and has become more elaborate and powerful over the years. It remains one of the Internet’s most important and utilized applications.

As with ordinary postal mail, e-mail is an asynchronous communication medium—people send and read messages when it is convenient for them, without having to coordinate with other people’s schedules. In contrast with postal mail, electronic mail is fast, easy to distribute, and inexpensive. Modern e-mail has many powerful features, including messages with attachments, hyperlinks, HTML-formatted text, and embedded photos.

In this section, we examine the application-layer protocols that are at the heart of Internet e-mail. But before we jump into an in-depth discussion of these protocols, let’s take a high-level view of the Internet mail system and its key components.

Figure 2.14 presents a high-level view of the Internet mail system. We see from this diagram that it has three major components: user agents, mail servers, and the Simple Mail Transfer Protocol (SMTP). We now describe each of these components in the context of a sender, Alice, sending an e-mail message to a recipient, Bob. User agents allow users to read, reply to, forward, save, and compose messages. Microsoft Outlook and Apple Mail are examples of user agents for e-mail. When Alice is finished composing her message, her user agent sends the message to her mail server, where the message is placed in the mail server’s outgoing message queue. When Bob wants to read a message, his user agent retrieves the message from his mailbox in his mail server.

Mail servers form the core of the e-mail infrastructure. Each recipient, such as Bob, has a mailbox located in one of the mail servers. Bob’s mailbox manages and maintains the messages that have been sent to him. A typical message starts its journey in the sender’s user agent, travels to the sender’s mail server, and travels to the recipient’s mail server, where it is deposited in the recipient’s mailbox. When Bob wants to access the messages in his mailbox, the mail server containing his mailbox authenticates Bob (with usernames and passwords). Alice’s mail server must also deal with failures in Bob’s mail server. If Alice’s server cannot deliver mail to Bob’s server, Alice’s server holds the message in a message queue and attempts to transfer the message later. Reattempts are often done every 30 minutes or so; if there is no success after several days, the server removes the message and notifies the sender (Alice) with an e-mail message.

../_images/150-0.png
align:

center

Figure 2.14 A high-level view of the Internet e-mail system

SMTP is the principal application-layer protocol for Internet electronic mail. It uses the reliable data transfer service of TCP to transfer mail from the sender’s mail server to the recipient’s mail server. As with most application-layer protocols, SMTP has two sides: a client side, which executes on the sender’s mail server, and a server side, which executes on the recipient’s mail server. Both the client and server sides of SMTP run on every mail server. When a mail server sends mail to other mail servers, it acts as an SMTP client. When a mail server receives mail from other mail servers, it acts as an SMTP server.

2.3.1 SMTP#

SMTP 定义于 RFC 5321,是互联网电子邮件的核心。如前所述,SMTP 将邮件从发送方邮件服务器传输到接收方邮件服务器。SMTP 的历史远早于 HTTP(最初的 SMTP RFC 可追溯到 1982 年,SMTP 在那之前就已经存在)。尽管 SMTP 拥有众多优点并广泛应用于互联网,但它仍是一种遗留技术,具有某些过时特性。例如,它限制所有邮件消息的正文(不仅是头部)为简单的 7 位 ASCII。这种限制在 20 世纪 80 年代初传输能力有限、没有人通过电子邮件发送大型附件或图像、音频、视频文件时是合理的。但在多媒体时代,这种限制带来不便 —— 二进制多媒体数据必须在通过 SMTP 发送前编码为 ASCII;在 SMTP 传输后还需再解码为二进制。回忆一下 第 2.2 节 中提到的,HTTP 不要求在传输前将多媒体数据编码为 ASCII。

为说明 SMTP 的基本操作,我们通过一个常见场景来演示。假设 Alice 想向 Bob 发送一个简单的 ASCII 消息。

  1. Alice 启动她的电子邮件用户代理,填写 Bob 的电子邮件地址(例如 bob@someschool.edu),撰写消息,并指示用户代理发送该消息。

  2. Alice 的用户代理将消息发送到她的邮件服务器,消息被放入消息队列中。

  3. SMTP 客户端部分在 Alice 的邮件服务器上运行,看到消息在队列中,于是建立到 SMTP 服务器(运行在 Bob 的邮件服务器上)的 TCP 连接。

  4. 经过初始的 SMTP 握手过程后,SMTP 客户端将 Alice 的消息通过 TCP 连接发送出去。

  5. 在 Bob 的邮件服务器上,SMTP 服务器部分接收该消息。Bob 的邮件服务器随后将消息放入 Bob 的邮箱中。

  6. Bob 启动他的用户代理,在方便的时候读取该消息。

此过程在 图 2.15 中进行了总结。

需要注意的是,SMTP 通常不使用中间邮件服务器转发邮件,即使两个邮件服务器位于地球两端。如果 Alice 的服务器在香港,而 Bob 的服务器在圣路易斯,TCP 连接就是香港与圣路易斯服务器之间的直接连接。特别地,如果 Bob 的邮件服务器宕机,消息会保留在 Alice 的邮件服务器上,等待后续尝试 —— 而不会转发到某个中间邮件服务器。

../_images/152-0.png

图 2.15 Alice 向 Bob 发送一封邮件

我们现在更深入地了解 SMTP 如何将邮件从发送服务器传送到接收服务器。SMTP 协议在许多方面与面对面的人际交流协议类似。首先,SMTP 客户端(运行在发送方邮件服务器主机上)通过 TCP 建立到 SMTP 服务器(运行在接收方邮件服务器主机上)端口 25 的连接。如果服务器宕机,客户端会稍后重试。一旦连接建立,服务器和客户端进行应用层握手 —— 就像人们在互相传递信息前会先相互介绍一样,SMTP 客户端和服务器也在传输信息前相互介绍。在握手阶段,SMTP 客户端会指明发件人和收件人的电子邮件地址。介绍完成后,客户端发送邮件。SMTP 借助 TCP 的可靠数据传输确保消息不出错地传送到服务器。如果客户端还有其他消息需要发送,会通过同一 TCP 连接重复该过程;否则,它会指示 TCP 关闭连接。

我们接下来来看一个 SMTP 客户端(C)与 SMTP 服务器(S)之间交换消息的示例对话。客户端主机名为 crepes.fr,服务器主机名为 hamburger.edu。标有 C: 的 ASCII 文本行为客户端通过其 TCP 套接字发送的内容,标有 S: 的文本行为服务器发送的内容。以下对话从 TCP 连接建立开始:

S:  220 hamburger.edu
C:  HELO crepes.fr
S:  250 Hello crepes.fr, pleased to meet you
C:  MAIL FROM: <alice@crepes.fr>
S:  250 alice@crepes.fr ... Sender ok
C:  RCPT TO: <bob@hamburger.edu>
S:  250 bob@hamburger.edu ... Recipient ok
C:  DATA
S:  354 Enter mail, end with ”.” on a line by itself
C:  Do you like ketchup?
C:  How about pickles?
C:  .
S:  250 Message accepted for delivery
C:  QUIT
S:  221 hamburger.edu closing connection

在上述示例中,客户端从邮件服务器 crepes.frhamburger.edu 发送消息(“Do you like ketchup? How about pickles?”)。在对话过程中,客户端发出了五个命令: HELO (HELLO 的缩写)、 MAIL FROMRCPT TODATAQUIT。这些命令直观易懂。客户端还发送了一行仅包含一个句点的行,表示消息结束。(在 ASCII 中,每封消息以 CRLF.CRLF 结束,CR 和 LF 分别表示回车和换行。)服务器对每个命令进行响应,响应包含一个代码及可选的英文解释说明。值得一提的是,SMTP 使用持久连接:如果发送服务器有多封邮件要发送给同一个接收服务器,它可以通过同一个 TCP 连接发送所有消息。每封消息开始于新的 MAIL FROM: crepes.fr,以句点标记结束,直到所有消息发送完毕后才发出 QUIT 命令。

强烈建议你使用 Telnet 与 SMTP 服务器直接对话。可执行如下命令:

telnet serverName 25

其中 serverName 是本地邮件服务器的名称。该命令会在本地主机与邮件服务器之间建立 TCP 连接。输入此行后,你应立即收到来自服务器的 220 回复。然后在适当时机依次输入 SMTP 命令 HELOMAIL FROMRCPT TODATACRLF.CRLFQUIT。我们也强烈建议你完成本章末尾的编程练习 3。在该练习中,你将构建一个实现 SMTP 客户端功能的简单用户代理,能够通过本地邮件服务器向任意收件人发送电子邮件。

原文

SMTP, defined in RFC 5321, is at the heart of Internet electronic mail. As mentioned above, SMTP transfers messages from senders’ mail servers to the recipients’ mail servers. SMTP is much older than HTTP. (The original SMTP RFC dates back to 1982, and SMTP was around long before that.) Although SMTP has numerous wonderful qualities, as evidenced by its ubiquity in the Internet, it is nevertheless a legacy technology that possesses certain archaic characteristics. For example, it restricts the body (not just the headers) of all mail messages to simple 7-bit ASCII. This restriction made sense in the early 1980s when transmission capacity was scarce and no one was e-mailing large attachments or large image, audio, or video files. But today, in the multimedia era, the 7-bit ASCII restriction is a bit of a pain —it requires binary multimedia data to be encoded to ASCII before being sent over SMTP; and it requires the corresponding ASCII message to be decoded back to binary after SMTP transport. Recall from Section 2.2 that HTTP does not require multimedia data to be ASCII encoded before transfer.

To illustrate the basic operation of SMTP, let’s walk through a common scenario. Suppose Alice wants to send Bob a simple ASCII message.

  1. Alice invokes her user agent for e-mail, provides Bob’s e-mail address (for example, bob@someschool.edu), composes a message, and instructs the user agent to send the message.

  2. Alice’s user agent sends the message to her mail server, where it is placed in a message queue.

  3. The client side of SMTP, running on Alice’s mail server, sees the message in the message queue. It opens a TCP connection to an SMTP server, running on Bob’s mail server.

  4. After some initial SMTP handshaking, the SMTP client sends Alice’s message into the TCP connection.

  5. At Bob’s mail server, the server side of SMTP receives the message. Bob’s mail server then places the message in Bob’s mailbox.

  6. Bob invokes his user agent to read the message at his convenience.

The scenario is summarized in Figure 2.15.

It is important to observe that SMTP does not normally use intermediate mail servers for sending mail, even when the two mail servers are located at opposite ends of the world. If Alice’s server is in Hong Kong and Bob’s server is in St. Louis, the TCP connection is a direct connection between the Hong Kong and St. Louis servers. In particular, if Bob’s mail server is down, the message remains in Alice’s mail server and waits for a new attempt—the message does not get placed in some intermediate mail server.

../_images/152-0.png

Figure 2.15 Alice sends a message to Bob

Let’s now take a closer look at how SMTP transfers a message from a sending mail server to a receiving mail server. We will see that the SMTP protocol has many similarities with protocols that are used for face-to-face human interaction. First, the client SMTP (running on the sending mail server host) has TCP establish a connection to port 25 at the server SMTP (running on the receiving mail server host). If the server is down, the client tries again later. Once this connection is established, the server and client perform some application-layer handshaking—just as humans often introduce themselves before transferring information from one to another, SMTP clients and servers introduce themselves before transferring information. During this SMTP handshaking phase, the SMTP client indicates the e- mail address of the sender (the person who generated the message) and the e-mail address of the recipient. Once the SMTP client and server have introduced themselves to each other, the client sends the message. SMTP can count on the reliable data transfer service of TCP to get the message to the server without errors. The client then repeats this process over the same TCP connection if it has other messages to send to the server; otherwise, it instructs TCP to close the connection.

Let’s next take a look at an example transcript of messages exchanged between an SMTP client (C) and an SMTP server (S). The hostname of the client is crepes.fr and the hostname of the server is hamburger.edu. The ASCII text lines prefaced with C: are exactly the lines the client sends into its TCP socket, and the ASCII text lines prefaced with S: are exactly the lines the server sends into its TCP socket. The following transcript begins as soon as the TCP connection is established.

S:  220 hamburger.edu
C:  HELO crepes.fr
S:  250 Hello crepes.fr, pleased to meet you
C:  MAIL FROM: <alice@crepes.fr>
S:  250 alice@crepes.fr ... Sender ok

C: RCPT TO: <bob@hamburger.edu> S: 250 bob@hamburger.edu … Recipient ok C: DATA S: 354 Enter mail, end with ”.” on a line by itself C: Do you like ketchup? C: How about pickles? C: . S: 250 Message accepted for delivery C: QUIT S: 221 hamburger.edu closing connection

In the example above, the client sends a message (“Do you like ketchup? How about pickles?”) from mail server crepes.fr to mail server hamburger.edu. As part of the dialogue, the client issued five commands: HELO (an abbreviation for HELLO), MAIL FROM, RCPT TO, DATA, and QUIT. These commands are self-explanatory. The client also sends a line consisting of a single period, which indicates the end of the message to the server. (In ASCII jargon, each message ends with CRLF.CRLF, where CR and LF stand for carriage return and line feed, respectively.) The server issues replies to each command, with each reply having a reply code and some (optional) English- language explanation. We mention here that SMTP uses persistent connections: If the sending mail server has several messages to send to the same receiving mail server, it can send all of the messages over the same TCP connection. For each message, the client begins the process with a new MAIL FROM: crepes.fr, designates the end of message with an isolated period, and issues QUIT only after all messages have been sent.

It is highly recommended that you use Telnet to carry out a direct dialogue with an SMTP server. To do this, issue

telnet serverName 25

where serverName is the name of a local mail server. When you do this, you are simply establishing a TCP connection between your local host and the mail server. After typing this line, you should immediately receive the 220 reply from the server. Then issue the SMTP commands HELO, MAIL FROM, RCPT TO, DATA, CRLF.CRLF, and QUIT at the appropriate times. It is also highly recommended that you do Programming Assignment 3 at the end of this chapter. In that assignment, you’ll build a simple user agent that implements the client side of SMTP. It will allow you to send an e-mail message to an arbitrary recipient via a local mail server.

2.3.2 与 HTTP 的对比#

2.3.2 Comparison with HTTP

现在我们简要比较一下 SMTP 和 HTTP。这两个协议都用于在主机之间传输文件:HTTP 将文件(也称为对象)从 Web 服务器传输到 Web 客户端(通常是浏览器);SMTP 将文件(即电子邮件消息)从一个邮件服务器传输到另一个邮件服务器。在传输文件时,持久性 HTTP 和 SMTP 都使用持久连接。因此,这两个协议具有一些共同特性。然而,它们之间也存在重要差异。首先,HTTP 主要是一个 拉取协议(pull protocol) —— 某人将信息加载到 Web 服务器上,用户通过 HTTP 在方便时从服务器拉取信息。特别地,TCP 连接由想要接收文件的机器发起。而 SMTP 主要是一个 推送协议(push protocol) —— 发送方邮件服务器将文件推送到接收方邮件服务器。特别地,TCP 连接由想要发送文件的机器发起。

第二个差异,我们之前已经提到,SMTP 要求每条消息(包括消息正文)必须为 7 位 ASCII 格式。如果消息包含非 7 位 ASCII 的字符(例如带重音符的法语字符)或包含二进制数据(如图像文件),则必须将消息编码为 7 位 ASCII。而 HTTP 数据不受此限制。

第三个重要差异与文本和图像(以及可能的其他媒体类型)组成的文档的处理方式有关。如我们在 第 2.2 节 中了解到的,HTTP 为每个对象封装一个独立的 HTTP 响应消息。而 SMTP 将所有消息对象放入一条消息中。

原文

Let’s now briefly compare SMTP with HTTP. Both protocols are used to transfer files from one host to another: HTTP transfers files (also called objects) from a Web server to a Web client (typically a browser); SMTP transfers files (that is, e-mail messages) from one mail server to another mail server. When transferring the files, both persistent HTTP and SMTP use persistent connections. Thus, the two protocols have common characteristics. However, there are important differences. First, HTTP is mainly a pull protocol — someone loads information on a Web server and users use HTTP to pull the information from the server at their convenience. In particular, the TCP connection is initiated by the machine that wants to receive the file. On the other hand, SMTP is primarily a push protocol —the sending mail server pushes the file to the receiving mail server. In particular, the TCP connection is initiated by the machine that wants to send the file.

A second difference, which we alluded to earlier, is that SMTP requires each message, including the body of each message, to be in 7-bit ASCII format. If the message contains characters that are not 7-bit ASCII (for example, French characters with accents) or contains binary data (such as an image file), then the message has to be encoded into 7-bit ASCII. HTTP data does not impose this restriction.

A third important difference concerns how a document consisting of text and images (along with possibly other media types) is handled. As we learned in Section 2.2, HTTP encapsulates each object in its own HTTP response message. SMTP places all of the message’s objects into one message.

2.3.3 邮件消息格式#

2.3.3 Mail Message Formats

当 Alice 写一封普通的邮政邮件给 Bob 时,她可能在信的开头写上各种附加的头部信息,如 Bob 的地址、她自己的回信地址和日期。类似地,当一封电子邮件从一个人发送给另一个人时,在消息正文之前也会有一个包含附加信息的头部。此类附加信息包含在一系列头部行中,这些头部行定义在 RFC 5322 中。头部行与消息正文之间通过一个空行(即 CRLF)分隔。 RFC 5322 规定了邮件头部行的精确格式及其语义解释。与 HTTP 一样,每个头部行包含可读文本,由关键字、冒号以及对应值组成。其中一些关键字是必需的,另一些是可选的。每个头部必须包含一个 From: 行和一个 To: 行;头部还可以包含一个 Subject: 行以及其他可选的头部行。需要注意的是,这些头部行与我们在 第 2.4.1 节 中研究的 SMTP 命令是不同的(尽管它们包含一些相同的词,如 “from” 和 “to”)。该节中的命令属于 SMTP 握手协议的一部分;而本节中的头部行则是邮件消息本身的一部分。

一个典型的消息头如下所示:

From: alice@crepes.fr
To: bob@hamburger.edu
Subject: Searching for the meaning of life.

在消息头之后是一个空行;随后是消息正文(以 ASCII 编码)。你应该使用 Telnet 向邮件服务器发送一条包含若干头部行(包括 Subject: 行)的消息。为此,请执行 telnet serverName 25,具体方法如 第 2.4.1 节 中所述。

原文

When Alice writes an ordinary snail-mail letter to Bob, she may include all kinds of peripheral header information at the top of the letter, such as Bob’s address, her own return address, and the date. Similarly, when an e-mail message is sent from one person to another, a header containing peripheral information precedes the body of the message itself. This peripheral information is contained in a series of header lines, which are defined in RFC 5322. The header lines and the body of the message are separated by a blank line (that is, by CRLF). RFC 5322 specifies the exact format for mail header lines as well as their semantic interpretations. As with HTTP, each header line contains readable text, consisting of a keyword followed by a colon followed by a value. Some of the keywords are required and others are optional. Every header must have a From: header line and a To: header line; a header may include a Subject: header line as well as other optional header lines. It is important to note that these header lines are different from the SMTP commands we studied in Section 2.4.1 (even though they contain some common words such as “from” and “to”). The commands in that section were part of the SMTP handshaking protocol; the header lines examined in this section are part of the mail message itself.

A typical message header looks like this:

From: alice@crepes.fr
To: bob@hamburger.edu
Subject: Searching for the meaning of life.

After the message header, a blank line follows; then the message body (in ASCII) follows. You should use Telnet to send a message to a mail server that contains some header lines, including the Subject: header line. To do this, issue telnet serverName 25, as discussed in Section 2.4.1.

2.3.4 邮件访问协议#

2.3.4 Mail Access Protocols

一旦 SMTP 将消息从 Alice 的邮件服务器传输到 Bob 的邮件服务器,该消息就被放入 Bob 的邮箱中。在整个讨论过程中,我们默认为 Bob 通过登录服务器主机并执行在该主机上运行的邮件读取器来阅读他的邮件。直到 1990 年代初期,这是标准的做法。但如今,邮件访问采用了客户端-服务器架构——典型用户在自己的终端系统上(例如办公室电脑、笔记本电脑或智能手机)运行客户端程序来阅读电子邮件。通过在本地 PC 上运行邮件客户端,用户可以享受丰富的功能,包括查看多媒体消息和附件的能力。

既然 Bob(收件人)在其本地 PC 上执行用户代理,那么也可以考虑将一个邮件服务器放置在他的本地 PC 上。采用这种方式,Alice 的邮件服务器就可以直接与 Bob 的 PC 通信。然而,这种方式存在问题。请记住,邮件服务器管理邮箱,并运行 SMTP 的客户端和服务器端。如果 Bob 的邮件服务器位于其本地 PC 上,那么 Bob 的 PC 就必须始终保持开机并连接互联网,以便接收随时可能到达的新邮件。这对许多互联网用户来说并不现实。相反,典型用户在本地 PC 上运行用户代理,但访问存储在始终在线的共享邮件服务器中的邮箱。这个邮件服务器与其他用户共享,通常由用户的 ISP(例如大学或公司)维护。

现在让我们来看看当一封电子邮件从 Alice 发送给 Bob 时,它所经过的路径。我们刚刚了解到,在路径的某个点上,这封电子邮件需要被投递到 Bob 的邮件服务器。这可以通过让 Alice 的用户代理直接将邮件发送给 Bob 的邮件服务器来实现,并且可以使用 SMTP ——实际上,SMTP 就是为将电子邮件从一个主机推送到另一个主机而设计的。然而,通常情况下,发送方的用户代理不会直接与接收方的邮件服务器通信。如 图 2.16 所示,Alice 的用户代理使用 SMTP 将电子邮件推送到她的邮件服务器,然后 Alice 的邮件服务器作为 SMTP 客户端将邮件中继到 Bob 的邮件服务器。为什么要采用这个两步过程?主要是因为如果不通过 Alice 的邮件服务器中继,Alice 的用户代理就无法应对无法到达的目标邮件服务器。通过让 Alice 首先将电子邮件存入她自己的邮件服务器,Alice 的邮件服务器可以每隔 30 分钟尝试将消息发送给 Bob 的邮件服务器,直到 Bob 的邮件服务器恢复正常。(如果 Alice 的邮件服务器宕机,她还可以向系统管理员抱怨!)SMTP RFC 定义了如何使用 SMTP 命令在多个 SMTP 服务器之间中继消息。

../_images/156-0.png

图 2.16 电子邮件协议及其通信实体

但谜题还缺少最后一块拼图!像 Bob 这样的收件人,在本地 PC 上运行用户代理,该如何获取存储在其 ISP 的邮件服务器中的消息呢?请注意,Bob 的用户代理无法使用 SMTP 获取邮件,因为获取消息是拉取操作,而 SMTP 是推送协议。这个问题通过引入一种特殊的邮件访问协议来完成拼图,该协议将消息从 Bob 的邮件服务器传输到其本地 PC。目前流行的邮件访问协议包括 Post Office Protocol—Version 3 (POP3)Internet Mail Access Protocol (IMAP) 和 HTTP。

图 2.16 总结了用于互联网邮件的协议:SMTP 用于将邮件从发送者的邮件服务器传输到接收者的邮件服务器;SMTP 也用于将邮件从发送者的用户代理传输到发送者的邮件服务器。诸如 POP3 的邮件访问协议,用于将邮件从接收者的邮件服务器传输到接收者的用户代理。

原文

Once SMTP delivers the message from Alice’s mail server to Bob’s mail server, the message is placed in Bob’s mailbox. Throughout this discussion we have tacitly assumed that Bob reads his mail by logging onto the server host and then executing a mail reader that runs on that host. Up until the early 1990s this was the standard way of doing things. But today, mail access uses a client-server architecture—the typical user reads e-mail with a client that executes on the user’s end system, for example, on an office PC, a laptop, or a smartphone. By executing a mail client on a local PC, users enjoy a rich set of features, including the ability to view multimedia messages and attachments.

Given that Bob (the recipient) executes his user agent on his local PC, it is natural to consider placing a mail server on his local PC as well. With this approach, Alice’s mail server would dialogue directly with Bob’s PC. There is a problem with this approach, however. Recall that a mail server manages mailboxes and runs the client and server sides of SMTP. If Bob’s mail server were to reside on his local PC, then Bob’s PC would have to remain always on, and connected to the Internet, in order to receive new mail, which can arrive at any time. This is impractical for many Internet users. Instead, a typical user runs a user agent on the local PC but accesses its mailbox stored on an always-on shared mail server. This mail server is shared with other users and is typically maintained by the user’s ISP (for example, university or company).

Now let’s consider the path an e-mail message takes when it is sent from Alice to Bob. We just learned that at some point along the path the e-mail message needs to be deposited in Bob’s mail server. This could be done simply by having Alice’s user agent send the message directly to Bob’s mail server. and this could be done with SMTP—indeed, SMTP has been designed for pushing e-mail from one host to another. However, typically the sender’s user agent does not dialogue directly with the recipient’s mail server. Instead, as shown in Figure 2.16, Alice’s user agent uses SMTP to push the e-mail message into her mail server, then Alice’s mail server uses SMTP (as an SMTP client) to relay the e-mail message to Bob’s mail server. Why the two-step procedure? Primarily because without relaying through Alice’s mail server, Alice’s user agent doesn’t have any recourse to an unreachable destination mail server. By having Alice first deposit the e-mail in her own mail server, Alice’s mail server can repeatedly try to send the message to Bob’s mail server, say every 30 minutes, until Bob’s mail server becomes operational. (And if Alice’s mail server is down, then she has the recourse of complaining to her system administrator!) The SMTP RFC defines how the SMTP commands can be used to relay a message across multiple SMTP servers.

../_images/156-0.png

Figure 2.16 E-mail protocols and their communicating entities

But there is still one missing piece to the puzzle! How does a recipient like Bob, running a user agent on his local PC, obtain his messages, which are sitting in a mail server within Bob’s ISP? Note that Bob’s user agent can’t use SMTP to obtain the messages because obtaining the messages is a pull operation, whereas SMTP is a push protocol. The puzzle is completed by introducing a special mail access protocol that transfers messages from Bob’s mail server to his local PC. There are currently a number of popular mail access protocols, including Post Office Protocol—Version 3 (POP3), Internet Mail Access Protocol (IMAP), and HTTP.

Figure 2.16 provides a summary of the protocols that are used for Internet mail: SMTP is used to transfer mail from the sender’s mail server to the recipient’s mail server; SMTP is also used to transfer mail from the sender’s user agent to the sender’s mail server. A mail access protocol, such as POP3, is used to transfer mail from the recipient’s mail server to the recipient’s user agent.

POP3#

POP3 是一种极其简单的邮件访问协议。其定义见 RFC 1939,该 RFC 简短且易读。由于协议非常简单,其功能也相当有限。POP3 会在用户代理(客户端)打开到邮件服务器(服务器)110 端口的 TCP 连接时启动。在建立 TCP 连接后,POP3 会经历三个阶段:授权、事务和更新。在第一个阶段 —— 授权阶段,用户代理发送用户名和密码(明文)来认证用户。在第二阶段 —— 事务阶段,用户代理检索消息;在此阶段,用户代理还可以标记消息为删除、移除删除标记以及获取邮件统计信息。第三阶段 —— 更新阶段,在客户端发出 quit 命令并结束 POP3 会话后进行;此时,邮件服务器会删除所有被标记为删除的消息。

在 POP3 的一次事务中,用户代理发出命令,服务器对每个命令作出响应。可能的响应有两种: +OK (有时后接从服务器到客户端的数据),表示前一个命令正常;-ERR,表示前一个命令出错。

授权阶段有两个主要命令: user <username>pass <password>。为了说明这两个命令,建议你直接使用 Telnet 连接到 POP3 服务器,端口号为 110,并发出这些命令。假设 mailServer 是你的邮件服务器名称。你会看到类似如下输出:

telnet mailServer 110
+OK POP3 server ready
user bob
+OK
pass hungry
+OK user successfully logged on

如果你拼写错误某个命令,POP3 服务器将返回 -ERR 消息。

现在我们来看事务阶段。使用 POP3 的用户代理通常可以配置为“下载并删除”或“下载并保留”。POP3 用户代理发出的命令序列取决于其工作模式。在下载并删除模式中,用户代理将发出 listretrdele 命令。例如,假设用户邮箱中有两条消息。以下对话中, C: (客户端)为用户代理, S: (服务器)为邮件服务器。事务过程可能如下所示:

C: list
S: 1 498
S: 2 912
S: .
C: retr 1
S: (blah blah ...
S: .................
S: ..........blah)
S: .
C: dele 1
C: retr 2
S: (blah blah ...
S: .................
S: ..........blah)
S: .
C: dele 2
C: quit
S: +OK POP3 server signing off

用户代理首先请求邮件服务器列出每条已存储消息的大小。然后用户代理检索并删除每条消息。请注意,在授权阶段之后,用户代理仅使用了四个命令: listretrdelequit。这些命令的语法在 RFC 1939 中有定义。处理完 quit 命令后,POP3 服务器进入更新阶段,并从邮箱中移除消息 1 和 2。

该下载并删除模式的问题在于收件人 Bob 可能是个游牧用户,可能希望从多台设备上访问邮件,例如他的办公电脑、家用电脑和便携设备。下载并删除模式会将 Bob 的邮件分散在这三台机器上;特别是,如果 Bob 首先在办公室电脑上阅读了某封邮件,他晚上回家后就无法再在便携设备上阅读该邮件了。而在下载并保留模式中,用户代理在下载邮件后保留服务器上的副本。这样 Bob 就可以从不同的设备上重复阅读邮件;他可以在工作时阅读一封邮件,然后在周末从家里再次访问。

在用户代理与邮件服务器之间的 POP3 会话期间,POP3 服务器会维护一些状态信息;尤其是,它会记录哪些用户邮件被标记为删除。然而,POP3 服务器不会在多个会话之间保留状态信息。这种跨会话无状态的特性极大地简化了 POP3 服务器的实现。

原文

POP3 is an extremely simple mail access protocol. It is defined in [RFC 1939] , which is short and quite readable. Because the protocol is so simple, its functionality is rather limited. POP3 begins when the user agent (the client) opens a TCP connection to the mail server (the server) on port 110. With the TCP connection established, POP3 progresses through three phases: authorization, transaction, and update. During the first phase, authorization, the user agent sends a username and a password (in the clear) to authenticate the user. During the second phase, transaction, the user agent retrieves messages; also during this phase, the user agent can mark messages for deletion, remove deletion marks, and obtain mail statistics. The third phase, update, occurs after the client has issued the quit command, ending the POP3 session; at this time, the mail server deletes the messages that were marked for deletion.

In a POP3 transaction, the user agent issues commands, and the server responds to each command with a reply. There are two possible responses: +OK (sometimes followed by server-to-client data), used by the server to indicate that the previous command was fine; and -ERR, used by the server to indicate that something was wrong with the previous command.

The authorization phase has two principal commands: user <username> and pass <password>. To illustrate these two commands, we suggest that you Telnet directly into a POP3 server, using port 110, and issue these commands. Suppose that mailServer is the name of your mail server. You will see something like:

telnet mailServer 110
+OK POP3 server ready
user bob
+OK
pass hungry
+OK user successfully logged on

If you misspell a command, the POP3 server will reply with an -ERR message.

Now let’s take a look at the transaction phase. A user agent using POP3 can often be configured (by the user) to “download and delete” or to “download and keep.” The sequence of commands issued by a POP3 user agent depends on which of these two modes the user agent is operating in. In the download-and-delete mode, the user agent will issue the list, retr, and dele commands. As an example, suppose the user has two messages in his or her mailbox. In the dialogue below, C: (standing for client) is the user agent and S: (standing for server) is the mail server. The transaction will look something like:

C: list
S: 1 498
S: 2 912
S: .
C: retr 1
S: (blah blah ...
S: .................
S: ..........blah)
S: .
C: dele 1
C: retr 2
S: (blah blah ...
S: .................
S: ..........blah)
S: .
C: dele 2
C: quit
S: +OK POP3 server signing off

The user agent first asks the mail server to list the size of each of the stored messages. The user agent then retrieves and deletes each message from the server. Note that after the authorization phase, the user agent employed only four commands: list, retr, dele, and quit. The syntax for these commands is defined in RFC 1939. After processing the quit command, the POP3 server enters the update phase and removes messages 1 and 2 from the mailbox.

A problem with this download-and-delete mode is that the recipient, Bob, may be nomadic and may want to access his mail messages from multiple machines, for example, his office PC, his home PC, and his portable computer. The download-and-delete mode partitions Bob’s mail messages over these three machines; in particular, if Bob first reads a message on his office PC, he will not be able to reread the message from his portable at home later in the evening. In the download-and-keep mode, the user agent leaves the messages on the mail server after downloading them. In this case, Bob can reread messages from different machines; he can access a message from work and access it again later in the week from home.

During a POP3 session between a user agent and the mail server, the POP3 server maintains some state information; in particular, it keeps track of which user messages have been marked deleted. However, the POP3 server does not carry state information across POP3 sessions. This lack of state information across sessions greatly simplifies the implementation of a POP3 server.

IMAP#

使用 POP3 访问时,一旦 Bob 将邮件下载到本地机器,他可以创建邮件文件夹并将已下载的邮件移动到这些文件夹中。Bob 然后可以删除邮件、在文件夹之间移动邮件,或按发件人姓名或主题搜索邮件。但这种“文件夹和本地机器上的邮件”的模式对游牧用户来说是个问题,他们更希望在远程服务器上维护一个文件夹结构,以便可以从任何计算机访问。这在 POP3 中是不可能的 —— POP3 协议不提供创建远程文件夹并将消息分配给文件夹的能力。

为了解决这个问题以及其他问题,IMAP 协议被设计出来,其定义见 RFC 3501。与 POP3 一样,IMAP 是一种邮件访问协议。它具有比 POP3 更多的功能,但也显著更复杂。(因此客户端和服务器端的实现也复杂得多。)

IMAP 服务器会将每条消息关联到一个文件夹;当消息首次到达服务器时,它被关联到收件人的 INBOX 文件夹。收件人随后可以将消息移动到用户创建的新文件夹中、读取消息、删除消息,等等。IMAP 协议提供命令,允许用户创建文件夹并在文件夹之间移动消息。IMAP 还提供命令,允许用户在远程文件夹中搜索满足特定条件的消息。请注意,与 POP3 不同,IMAP 服务器在多个 IMAP 会话之间维护用户状态信息 —— 例如文件夹名称及哪些消息属于哪些文件夹。

IMAP 的另一个重要特性是,它支持一些命令,允许用户代理仅获取消息的一部分。例如,用户代理可以仅获取消息头,或仅获取一个多部分 MIME 消息中的某一部分。当用户代理与邮件服务器之间的连接带宽较低(例如低速调制解调器连接)时,此功能非常有用。带宽受限时,用户可能不希望下载邮箱中所有邮件,尤其是不愿意下载那些可能包含音频或视频片段的长消息。

原文

With POP3 access, once Bob has downloaded his messages to the local machine, he can create mail folders and move the downloaded messages into the folders. Bob can then delete messages, move messages across folders, and search for messages (by sender name or subject). But this paradigm— namely, folders and messages in the local machine—poses a problem for the nomadic user, who would prefer to maintain a folder hierarchy on a remote server that can be accessed from any computer. This is not possible with POP3—the POP3 protocol does not provide any means for a user to create remote folders and assign messages to folders. To solve this and other problems, the IMAP protocol, defined in [RFC 3501], was invented. Like POP3, IMAP is a mail access protocol. It has many more features than POP3, but it is also significantly more complex. (And thus the client and server side implementations are significantly more complex.)

An IMAP server will associate each message with a folder; when a message first arrives at the server, it is associated with the recipient’s INBOX folder. The recipient can then move the message into a new, user-created folder, read the message, delete the message, and so on. The IMAP protocol provides commands to allow users to create folders and move messages from one folder to another. IMAP also provides commands that allow users to search remote folders for messages matching specific criteria. Note that, unlike POP3, an IMAP server maintains user state information across IMAP sessions—for example, the names of the folders and which messages are associated with which folders.

Another important feature of IMAP is that it has commands that permit a user agent to obtain components of messages. For example, a user agent can obtain just the message header of a message or just one part of a multipart MIME message. This feature is useful when there is a low-bandwidth connection (for example, a slow-speed modem link) between the user agent and its mail server. With a low-bandwidth connection, the user may not want to download all of the messages in its mailbox, particularly avoiding long messages that might contain, for example, an audio or video clip.

基于 Web 的电子邮件#

Web-Based E-Mail

如今,越来越多的用户通过 Web 浏览器发送和访问电子邮件。Hotmail 在 1990 年代中期首次引入了基于 Web 的访问。现在,Google、Yahoo! 以及几乎所有大学和大型公司都提供基于 Web 的电子邮件服务。使用这种服务时,用户代理是一个普通的 Web 浏览器,用户通过 HTTP 与远程邮箱通信。当收件人(如 Bob)想访问其邮箱中的邮件时,电子邮件是通过 HTTP 协议从 Bob 的邮件服务器发送到 Bob 的浏览器,而不是使用 POP3 或 IMAP 协议。当发件人(如 Alice)想发送邮件时,电子邮件是通过 HTTP 从她的浏览器发送到她的邮件服务器,而不是通过 SMTP。然而,Alice 的邮件服务器仍然使用 SMTP 向其他邮件服务器发送消息,并从它们接收消息。

原文

More and more users today are sending and accessing their e-mail through their Web browsers. Hotmail introduced Web-based access in the mid 1990s. Now Web-based e-mail is also provided by Google, Yahoo!, as well as just about every major university and corporation. With this service, the user agent is an ordinary Web browser, and the user communicates with its remote mailbox via HTTP. When a recipient, such as Bob, wants to access a message in his mailbox, the e-mail message is sent from Bob’s mail server to Bob’s browser using the HTTP protocol rather than the POP3 or IMAP protocol. When a sender, such as Alice, wants to send an e-mail message, the e-mail message is sent from her browser to her mail server over HTTP rather than over SMTP. Alice’s mail server, however, still sends messages to, and receives messages from, other mail servers using SMTP.