【发布时间】:2017-09-14 05:11:51
【问题描述】:
这里有点奇怪,当将“UseTLS”设置为 utUseExplicitTLS 然后在其隐式 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 := 'test@test.com';
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;
【问题讨论】:
-
你描述的不可能。隐式 TLS 端口要求在连接后立即启动 TLS 握手,并在发送 SMTP 问候语之前完全完成。
utUseExplicitTLS在连接时不发送握手,因此Connect()将阻止等待从未发送过的问候,直到服务器断开连接或ReadTimeout过去,以先发生者为准。无论哪种方式,调用代码都无法发送任何电子邮件。 -
@RemyLebeau 你所说的是我所期待的行为,当上述第一次尝试时我感到震惊。作为检查,我同时运行了 Wireshark,它在第一次尝试时显示成功(也收到了电子邮件),但随后的尝试将超时,Wireshark 没有收到任何内容。
-
你所说的在 implicit TLS 端口上根本不可能。 TLS 握手是必需的。您很可能在第一次尝试时连接到一个非隐式 端口,然后在随后的尝试中连接到一个隐式 端口。使用 Wireshark 验证每个连接上使用的端口。
-
@RemyLebeau 我直到现在才看到你的回复,但我会发布似乎已经修复它的答案。