2017-01-16 119 views
1

我一直在使用的演示用Delphi 7.一切正常摆弄SMTP客户端和服务器组件在印第安纳波利斯9。但是,当我登录服务器时,演示仅显示电子邮件主题和邮件正文,From:To:字段未显示。印SMTP服务器和Telnet

下面的代码显示了AMsg缺乏相关数据。

procedure TForm1.IdSMTPServer1ReceiveMessageParsed(ASender: TIdCommand; 
    var AMsg: TIdMessage; RCPT: TIdEMailAddressList; 
    var CustomError: String); 
begin 
    // This is the main event if you have opted to have the idSMTPServer to do your parsing for you. 

    // The AMessage contains the completed TIdMessage. 

    // NOTE: Dont forget to add IdMessage to your USES clause! 

    ToLabel.Caption := AMsg.Recipients.EMailAddresses; 
    FromLabel.Caption := AMsg.From.Text; 
    SubjectLabel.Caption := AMsg.Subject; 
    Memo1.Lines := AMsg.Body; 

    // Implement your file system here :) 
end; 

有人可以提出一个理由吗? 首先,感谢雷米的回应。 其次,看来我不能在这里发表图片,然而,但这里是服务器的telnet会话https://postimg.org/image/f0n9j0kcx/的图片的链接。 telnet会话显示服务器响应。 也感谢提醒我关于Wireshark以及使用TIdLog组件的建议。

+0

欢迎来到StackOverflow。请显示您通过Telnet发送的实际命令,您可能会丢失一些东西。 –

+0

如何发布我的Telnet会话的图像?它是否在评论中出现在这里,还是我点击“回答你的问题”? – grasshopper

+0

如果您从终端窗口复制/粘贴实际的命令,而不是张贴图像,会更好。但无论哪种方式,请[编辑您的问题](http://stackoverflow.com/posts/41686677/edit)以包含新信息,请勿将其发布在答案或评论中。 –

回答

1

由于您没有显示您通过Telnet发送的实际SMTP命令,但您很可能会丢失TIdSMTP发送的必需命令/数据,因此很难确定地知道。看到正在交换的实际SMTP命令/响应,您可以使用数据包嗅探器像Wireshark的,或附加Indy的TIdLog...组件之一的TIdSMTP和/或TIdSMTPServer套接字连接。

是经由MAIL FROM命令收到并接受由服务器(见OnCommandMail事件)传递给在TIdSMTPServerThread(ASender.Thread).From财产OnReceive...事件的任何电子邮件地址。如果首先没有从MAIL FROM接受电子邮件地址,服务器将不会接受RCPT TO命令。如果您未指定OnCommandMail处理程序,则服务器将接受它收到的任何电子邮件地址。

,它们通过RCPT TO命令收到并接受由服务器(见OnCommandRCPT事件)的任何电子邮件地址传递给OnReceive...事件在RCPT参数,并在TIdSMTPServerThread(ASender.Thread).RCPTList财产。如果首先至少有一个电子邮件地址不被RCPT TO接受,服务器将不会接受DATA命令。如果您未指定OnCommandRCPT处理程序,则服务器将接受它收到的每个电子邮件地址。

OnReceiveMessage...事件中,提供的TIdMessage对象首先从仅在DATA命令中发送的原始电子邮件数据填充。仅在OnReceiveMessageParsed事件的情况下,之前通过RCPT TO接受的任何电子邮件地址将合并到TIdMessage.Recipients属性中(如果它们尚不存在)。但是,在MAIL FROM命令中收到的任何电子邮件地址都不会合并到TIdMessage.From属性中。

因此,取决于您在DATA命令中实际发送的电子邮件数据,AMsg.From属性可能是也可能不是空的。但AMsg.Recipients属性肯定不应该。

此外,别的要记住 - TIdSMTPServer是多线程(因为大多数Indy服务器)。它的事件是在工作线程的上下文中触发的,而不是主UI线程。您的代码直接从主UI线程之外访问VCL UI控件,这是不安全的并且可能导致各种问题。只要同步的代码运行在上下文中,您可以使用VCL的TThread.Synchronize()TThread.Queue()方法或Indy的TIdSyncTIdNotify类或您选择的任何其他线程安全同步机制与主UI线程同步必须只有主UI线程。