delphi - Indy SMTP 服务器 - 如何检测 CC 和 BCC 收件人?

标签 delphi smtp indy10

我正在尝试使用 Delphi 帮助、Indy 示例和 Google 开发 SMTP 中继服务器。

我刚刚开始,有一个虚拟 SMTP 客户端,它将测试消息发送到 SMTP 服务器,该服务器稍后将处理它并使用 SMTP 中继转发它。

在服务器上,我收到一个 OnRcpt对于每个收件人(我使用一个 To 、一个 CC 和一个 Bcc 进行测试)。

我还看到了 ToCC AMsg中的收件人当我处理OnMsgReceive时并转换AMsgTStringStream (适本地以 To:CC: 为前缀),但我没有看到 BCC那里。

问题:如何判断哪些地址是 To , CCBCC

<小时/>

这是一些非常简单的代码。我正在设置断点并检查收到的参数以尝试查看发生了什么

procedure TEmailMonitorMainForm.IdSMTPServerMsgReceive(ASender: TIdSMTPServerContext;
  AMsg: TStream; var VAction: TIdDataReply);
var
  LMsg : TIdMessage;
begin
  LMsg := TIdMessage.Create(Nil);
  LMsg.LoadFromStream(AMsg);
  LMsg.Free();   // breakpoint here  examine   Lmsg
end;         // IdSMTPServerMsgReceive()

[更新]当我发送时,然后<message>.BCCList.Count = 1 ,但是当我接收时,它是0,而接收到的 CClist.Count是 1,这是应该的。

最佳答案

At the server, I receive one OnRcpt for each recipient (I test with one To, one CC and one Bcc).

SMTP 协议(protocol)不区分收件人CCBCC 收件人。这是电子邮件格式的产物,通过其 To:Cc: header (没有 Bcc: header ,尽管 TIdMessage .SaveToFile() 创建一个,以便 TIdMessage.LoadFromFile() 可以重新加载它)。当 SMTP 客户端将电子邮件发送到 SMTP 服务器时,客户端会确定预期的收件人,并在发送给服务器的单独的 RCPT TO 命令中指定每个收件人(这就是允许 BCC 的原因) > 工作 - 电子邮件本身没有 Bcc: header ,但服务器会为每个 Bcc 收件人提供一个 RCPT TO 命令) 。 RCPT TO 地址是在 TIdSMTPServer.OnRcptTo 事件中指定的值,并收集在 TIdSMTPServerContext.RCPTList 属性中。这些地址是 SMTP 客户端明确请求的,并且是您应该将电子邮件发送到的唯一地址(而不是电子邮件 header 中指定的收件人)。

I also see the To and CC recipients in AMsg when I handle OnMsgReceive and convert AMsg to a TStringStream (suitably prefixed with To: and CC:), but I don't see the BCC there.

对于 SMTP 服务器而言,实际的电子邮件本身只是任意数据。它应按原样交付给每个请求的收件人。这就是为什么电子邮件数据在 TIdSMTPServer.OnMsgReceive 事件中作为 TStream 提供,以及为什么 Indy 10 中的 TIdSMTPServer 不提供 基于 TIdMessage 的事件,就像 Indy 9 及更早版本中所做的那样。

如果电子邮件位于 RFC 822/2822/5322格式(通常是这样),它将具有 To:Cc: header 。将此类电子邮件接收/加载到 TIdMessage 中时,这些 header 分别用于填充 TIdMessage.RecipientsTIdMessage.CCList 属性。但由于通常没有 Bcc: header (除非电子邮件是从 TIdMessage.SaveToFile() 创建的文件加载的),因此 TIdMessage.BCCList 不会被填写。

how do I tell which addresses were To, CC and BCC?

由于 SMTP 协议(protocol)本身不区分不同的收件人类型,因此区分它们的唯一方法是解析电子邮件,查看其 To:Cc: header 。 TIdSMTPServerContext.RCPTList 属性中不属于这两个 header 之一的任何地址都必须是Bcc 收件人。但是,不能保证 TIdSMTPServerContext.RCPTList 属性中的其他地址始终与 To:Cc: header 匹配(尽管它们通常会),因为从技术上讲,SMTP 客户端可以发送它想要的任何原始数据,并且 SMTP 会按原样传送它,而不关心它实际包含的内容。

Here's some exceedingly simple code.

不要使用TIdMessage.LoadFromStream()来解析TIdSMTPServer.OnMsgReceive提供的TStream对象事件!它并不总是能正常工作。技术原因已在 Embarcadero 和 AToZed 论坛中多次详细讨论,例如 this discussion 。您暂时需要使用以下解决方法。该问题将在 Indy 11 中得到解决:

procedure TEmailMonitorMainForm.IdSMTPServerMsgReceive(ASender: TIdSMTPServerContext; AMsg: TStream; var VAction: TIdDataReply);
var
  LMsg : TIdMessage;
  LClient: TIdMessageClient;
  LIO: TIdIOHandlerStreamMsg;
begin
  LMsg := TIdMessage.Create(Nil);
  try
    //LMsg.LoadFromStream(AMsg);    
    LClient := TIdMessageClient.Create;
    try
      LIO := TIdIOHandlerStreamMsg.Create(LClient, AMsg);
      LIO.FreeStreams := False;
      LIO.EscapeLines := True;
      LIO.Open;
      LClient.IOHandler := LIO;
      LClient.ProcessMessage(LMsg, False);
    finally
      LClient.Free;
    end;
    // now you can use LMsg as needed...
  finally
    LMsg.Free;
  end;
end;

关于delphi - Indy SMTP 服务器 - 如何检测 CC 和 BCC 收件人?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25576292/

相关文章:

ios - iphone 重启后后台定位服务没有重启

delphi - 在 DCOM 中设置远程启动

java - GMAIL:发送一封包含多个地址的电子邮件或发送多封电子邮件。哪一个更好?

delphi - 在XE2上重新编译indy10源代码失败

delphi - UDP 数据包未被 Wireshark 捕获,但被 UDP 应用程序捕获

delphi - 将 Indy 10 IdHTTP 与 TLS 1.2 结合使用

delphi - 为什么我在 Delphi TMainMenu 中看不到热键下划线

delphi - 如何使我的自定义控件在设计时完全可点击?

java - 如何使用带有 OAuth2 身份验证的 Gmail SMTP 使用 java 邮件发送邮件?

smtp - 使用 SMTP 适配器在 BizTalk 中发送带有多个 pdf 附件的 HTML 电子邮件