2017-09-14 70 views
0

在将UseTLS设置为utUseExplicitTLS并在其隐式TLS端口上连接到邮件服务器时,第一次尝试允许连接并发送电子邮件,随后在该端口上的尝试正确失败。在Delphi中使用Indy 10.6.2.5341的SMTP隐式TLS和显式TLS

只是想知道如果任何人有任何想法如何避免在初始连接和发送误报。

该检查用于处理非标准端口可能正在用于用户的邮件服务器。几乎所有我见过的例子都假设总会提供正确的信息。

下面是处理它(不包括错误日志)的代码部分:

function SendTestEmail(EmailAddress: String): Boolean; 
var 
    EmailMessage: TidMessage; 
begin 
    IdSMTPEmail.AuthType := satDefault 
    IdSMTPEmail.Username := ...; 
    IdSMTPEmail.Password := ...; 
    IdSMTPEmail.Port := 465; 

    IdSMTPEmail.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdSMTPEmail); 
    IdSMTPEmail.UseTLS := utUseExplicitTLS; 
    TIdSSLIOHandlerSocketOpenSSL(IdSMTPEmail.IOHandler).SSLOptions.Method := sslvTLSv1_2; 
    try 
    // Connect 
    IdSMTPEmail.Connect('smtp.gmail.com'); 

    try 
     // Create 
     EmailMessage := TidMessage.Create(nil); 

     try 
     // Set values 
     EmailMessage.Body.Add('Test Email'); 
     EmailMessage.Subject := 'Test Email'; 

     // Set sender details 
     EmailMessage.From.Address := '[email protected]'; 
     EmailMessage.From.Name := 'SSL Test'; 

     // Set recipient 
     EmailMessage.Recipients.Add.Address := EmailAddress; 

     try 
      // Send message 
      IdSMTPEmail.Send(EmailMessage); 

     except 
      // Exception 
      on E: EIdSMTPReplyError do 
      begin 
      // Result 
      Result := False; 
      end; 
     end; 

     finally 
     // Free email 
     EmailMessage.Free; 
     end; 

    finally 
     // Disconnect 
     IdSMTPEmail.Disconnect; 
    end; 

    except 
    // Exception 
    on E: Exception do 
    begin 
     IdSMTPEmail.Disconnect; 
     // Result 
     Result := False; 
    end; 
    end; 
end; 
+0

你所描述的是不可能的。隐式TLS端口要求在连接时立即启动TLS握手,并在发送SMTP问候语之前完全完成TLS握手。 'utUseExplicitTLS'不会在连接时发送握手信号,所以'Connect()'将阻止等待一个永远不会发送的问候,直到服务器断开连接或经过'ReadTimeout'(以先发生者为准)。无论哪种方式,调用代码将无法发送足够多的电子邮件。 –

+0

@RemyLebeau你说过的话是我期待的行为,当上面的第一次尝试工作时,它被惊呆了。作为一个支票,我同时运行了Wireshark,它在第一次尝试(也收到了电子邮件)中显示成功,但随后的尝试超时并且Wireshark没有收到任何内容。 – Aaron

+0

你说的根本不可能在**隐式TLS **端口上。 TLS握手是*必填*。您很可能在第一次尝试时连接到*非隐式*端口,然后在随后的尝试中连接到*隐式*端口。使用Wireshark来验证每个连接上使用的端口。 –

回答

0

使用下面的代码,正确失败的试图通过电子邮件发送给端口465

我不所有的尝试甚至假装明白为什么这个作品,但我原来没有。

function SendTestEmail(EmailAddress: String): Boolean; 
var 
    EmailMessage: TidMessage; 
    IdSSLHandler: TIdSSLIOHandlerSocketOpenSSL; 
begin 
    IdSMTPEmail.AuthType := satDefault; 

    IdSSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create; 
    IdSSLHandler.SSLOptions.Method := sslvTLSv1_2; 

    IdSMTPEmail.IOHandler := IdSSLHandler; 
    IdSMTPEmail.UseTLS := utUseExplicitTLS; 

    IdSMTPEmail.Username := ...; 
    IdSMTPEmail.Password := ...; 
    IdSMTPEmail.Port := 465; 

    try 
    // Connect 
    IdSMTPEmail.Connect('smtp.gmail.com'); 

    try 
     // Create 
     EmailMessage := TidMessage.Create(nil); 

     try 
     // Set values 
     EmailMessage.Body.Add('Test Email'); 
     EmailMessage.Subject := 'Test Email'; 

     // Set sender details 
     EmailMessage.From.Address := '[email protected]'; 
     EmailMessage.From.Name := 'SSL Test'; 

     // Set recipient 
     EmailMessage.Recipients.Add.Address := EmailAddress; 

     try 
      // Send message 
      IdSMTPEmail.Send(EmailMessage); 

     except 
      // Exception 
      on E: EIdSMTPReplyError do 
      begin 
      // Result 
      Result := False; 
      end; 
     end; 

     finally 
     // Free email 
     EmailMessage.Free; 
     end; 

    finally 
     // Disconnect 
     IdSMTPEmail.Disconnect; 
    end; 

    except 
    // Exception 
    on E: Exception do 
    begin 
     IdSMTPEmail.Disconnect; 
     // Result 
     Result := False; 
    end; 
    end; 
end;