第 1 章 - Azure RTOS NetX Duo SMTP 客户端简介

简单邮件传输协议 (SMTP) 是一种用于跨网络和 Internet 传输邮件的协议。 它利用可靠的传输控制协议 (TCP) 服务来实现其内容传输功能。

NetX Duo SMTP 客户端要求

NetX Duo SMTP 客户端要求创建 NetX Duo IP 实例和 NetX Duo 数据包池。 SMTP 客户端使用 TCP 套接字来连接到已知端口 25 上的 SMTP 服务器。因此,必须先通过在之前创建的 IP 实例上调用 nx_tcp_enable 服务来启用 TCP。

SMTP 客户端创建调用 (nxd_smtp_client_create) 需要之前创建的数据包池,用于向服务器传输 SMTP 命令,以及发送实际邮件。 数据包有效负载取决于预期的邮件内容大小,并且必须容纳 TCP、IP 头和 MAC 头。 (请注意,IPv6 头是 40 字节,而 IPv4 头是 20 字节。)

如果一个数据包无法容纳整个邮件,那么 SMTP 客户端会分配额外的数据包来容纳邮件的其余部分。

NetX Duo SMTP 客户端约束

虽然 NetX Duo SMTP 协议实现了 RFC 2821 和2554 标准,但有一些约束:

  1. NetX Duo SMTP 客户端只支持 LOGIN 和 PLAIN 身份验证,不支持 CRAM-MD5 摘要式身份验证。
  2. NetX Duo SMTP 客户端邮件被限制为,每个邮件项只能有一个收件人,每个与 SMTP 服务器的 TCP 连接只能有一个邮件。
  3. 不支持 VRFY、SEND、SOML、EXPN、SAML、ETRN、TURN 和 SIZE SMTP 选项。
  4. SMTP 客户端不是通常用于创建邮件的邮件浏览器(“邮件用户代理”)。 它只是一个“邮件传输代理”。 它将按照 RFC 2821 中规定的方式为 SMTP 传输提供必要的邮件正文处理。 它不会检查内容中的语法(例如收件人和反向路径)是否正确。 对于邮件缓冲区中的内容(例如 MIME 数据或明文邮件),没有任何限制。 RFC 2822 中规定的关于添加头和邮件正文的邮件格式超出了 SMTP 客户端 API 的范围。

NetX Duo SMTP 客户端支持的命令

在与 SMTP 服务器进行邮件会话期间,NetX Duo SMTP 客户端使用以下命令。

  • EHLO:客户端希望发起会话,其中包括可以从 SMTP 服务器使用的部分或全部扩展协议 SMTP 服务。 这是默认值。
  • HELO:客户端希望发起仅限于基本 SMTP 服务的会话。
  • MAIL:客户端希望服务器接收客户端邮件。
  • AUTH:客户端希望发起由服务器执行身份验证。
  • RCPT:客户端希望提交另一个作为邮件传递到的主机的邮箱。
  • DATA:客户端希望发起向服务器发送邮件数据。
  • QUIT:客户端希望终止会话。

入门

SMTP 客户端应用程序创建 IP 实例,并在此 IP 实例上启用 TCP。 然后,它使用以下服务创建 SMTP 客户端:

UINT nxd_smtp_client_create(NX_SMTP_CLIENT *client_ptr,
    NX_IP *ip_ptr, NX_PACKET_POOL
    *client_packet_pool_ptr,
    CHAR *username, CHAR *password,
    CHAR *from_address,
    CHAR *client_domain,
    UINT authentication_type,
    NXD_ADDRESS *server_address, UINT port);

client_packet_pool_ptr 是指向之前创建的数据包池的指针,SMTP 客户端使用此数据包池将邮件发送到 SMTP 服务器。

请注意,应用程序必须提供本地设备的 from_address 和服务器 IP 地址。 所有地址都必须是完全限定的域名。 完全限定的域名由本地部分和域名(以“@”字符分隔)组成。 请注意,SMTP 客户端不会检查下面 nx_smtp_mail_send 服务中 from_address 或 recipient_address 的语法。

在创建 SMTP 客户端后,SMTP 客户端应用程序会创建包含格式正确的 SMTP 邮件的邮件项,并使用以下 API 向 SMTP 客户端发出邮件发送请求:

UINT nx_smtp_mail_send(NX_SMTP_CLIENT *client_ptr,
    CHAR *recipient_address, UINT priority,
    CHAR *subject, CHAR *mail_body,
    UINT mail_body_length);

从用户的角度来看,通过 IPv4 或 IPv6 运行 SMTP 客户端基本上没有区别。 这两种 IP 协议的差异在基础 NetX Duo 层中进行处理。

请注意,要发送邮件的应用程序必须在 nx_smtp_client_mail 调用中提供收件人地址。

对于身份验证,用户名可以是完全限定的域名,也可以是显示用户名。 这取决于服务器如何执行身份验证。

本用户指南后面的“小型示例”部分中的演示展示了应如何设置邮件格式。 如果邮件项已成功发送,则状态为 NX_SUCCESS。 如果出错,无论是内部错误、TCP 连接中断,还是收到服务器答复错误代码,nx_smtp_mail_send 都会返回非零错误状态。

在发送邮件项时,NetX Duo SMTP 客户端会新建与 SMTP 服务器的 TCP 连接,并开始 SMTP 会话。 在此会话中,客户端将一系列命令作为 SMTP 协议的一部分发送到 SMTP 服务器,最终会发送实际邮件。 然后,不管 SMTP 会话的结果如何,TCP 连接都会被终止。

在邮件传输后,无论是成功还是失败,SMTP 客户端都会恢复为“初始”状态,并可用于另一个邮件传输会话。

NetX Duo SMTP 身份验证

身份验证是一种 SMTP 客户端向 SMTP 服务器证明其身份并将邮件作为可信用户传递的方法。 大多数商业 SMTP 服务器都要求对客户端进行身份验证。

身份验证数据通常由发件人的用户名和密码组成。 在身份验证质询期间,服务器提示提供此类信息,客户端以编码格式发送所请求的数据作为响应。 服务器对数据进行解码,并尝试在其用户数据库中查找匹配项。 如果找到,服务器就会指明身份验证成功。 RFC 2554 中定义了 SMTP 身份验证。

有两种形式的身份验证,即基本身份验证和摘要式身份验证。 摘要式身份验证不受当前的 NetX Duo SMTP 客户端支持,所以本文将不讨论。 基本身份验证相当于前面介绍的用户名和密码身份验证。 在 SMTP 基本身份验证中,用户名和密码都采用 base64 编码。 基本身份验证的优点是易于实现和应用广泛。 基本身份验证的主要缺点是,在请求中公开传输用户名和密码数据。

纯文本身份验证

NetX Duo SMTP 客户端发送包含 PLAIN 参数的 AUTH 命令。 如果 NetX Duo SMTP 服务器支持这种类型的身份验证,则会答复 334 答复代码。 客户端向服务器答复一条包含 base64 编码的用户名和密码的消息。 如果服务器确定客户端身份验证成功,则会响应 235 成功代码。

登录身份验证

NetX Duo SMTP 客户端发送包含 LOGIN 参数的 AUTH 命令。 如果 NetX Duo SMTP 服务器支持这种类型的身份验证,则会答复 334 答复代码作为身份验证“质询”的开始。 它将 base64 编码的提示(通常是“Username”)发送回客户端。 客户端对提示进行解码,然后答复 base64 编码的用户名。 如果服务器接受客户端用户名,则会发送 base64 编码的提示,要求提供客户端密码。 客户端响应 base64 编码的密码。 如果服务器确定客户端身份验证成功,则会响应 235 成功代码。

无身份验证

一些 SMTP 服务器没有配置身份验证。 如果是这样,它们对客户端 EHLO 邮件的 250 响应将不会列出任何身份验证类型。 但是,没有列出任何身份验证类型并不一定意味着服务器不需要或不支持身份验证。 在这种情况下,如果为客户端配置了 PLAIN 或 LOGIN 身份验证,那么 NetX Duo 客户端线程任务默认为 PLAIN。 如果为客户端配置了 NONE,则会跳过身份验证步骤,并且 SMTP 状态前进到 MAIL 状态。

请注意,如果客户端被配置为不进行身份验证,而 SMTP 服务器确实支持身份验证,那么客户端身份验证类型会切换为 PLAIN。

NetX Duo SMTP 客户端支持的 RFC

NetX Duo SMTP 客户端 API 符合 RFC2821“简单邮件传输协议”和 RFC 2554“用于身份验证的 SMTP 服务扩展”。 “