C++ 使用Indy组件,我得到;“连接正常关闭”;错误,但仅在某些计算机上

C++ 使用Indy组件,我得到;“连接正常关闭”;错误,但仅在某些计算机上,c++,smtp,gmail,indy,C++,Smtp,Gmail,Indy,我开发的一款产品使用Indy组件发送电子邮件。它是在RAD Studio XE4(C++)中开发的。我试图找出为什么它在某些计算机上工作,而在其他计算机上却不工作。当然,它在我的开发盒上工作。在测试盒上,我要么收到“连接正常关闭”消息,要么收到套接字错误10054 两台机器正在加载相同的Indy文件。我的开发环境运行的是Win8.1,测试环境运行的是Win7,所以一些Windows DLL是不同的版本,但我怀疑这是问题所在 我编写了一个非常简单的测试应用程序,它展示了相同的行为 “我的开发”框上

我开发的一款产品使用Indy组件发送电子邮件。它是在RAD Studio XE4(C++)中开发的。我试图找出为什么它在某些计算机上工作,而在其他计算机上却不工作。当然,它在我的开发盒上工作。在测试盒上,我要么收到“连接正常关闭”消息,要么收到套接字错误10054

两台机器正在加载相同的Indy文件。我的开发环境运行的是Win8.1,测试环境运行的是Win7,所以一些Windows DLL是不同的版本,但我怀疑这是问题所在

我编写了一个非常简单的测试应用程序,它展示了相同的行为

“我的开发”框上的SMTP消息如下所示:

S: 220 smtp.gmail.com ESMTP vf11sm8649345igb.20 - gsmtp
C: EHLO ks-sayers-v60
S: 250-smtp.gmail.com at your service, [64.132.205.66]
S: 250-SIZE 35882577
S: 250-8BITMIME
S: 250-STARTTLS
S: 250-ENHANCEDSTATUSCODES
S: 250-PIPELINING
S: 250-CHUNKING
S: 250 SMTPUTF8
C: STARTTLS
S: 220 2.0.0 Ready to start TLS
C: EHLO ks-sayers-v60
S: 250-smtp.gmail.com at your service, [64.132.205.66]
S: 250-SIZE 35882577
S: 250-8BITMIME
S: 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
S: 250-ENHANCEDSTATUSCODES
S: 250-PIPELINING
S: 250-CHUNKING
S: 250 SMTPUTF8
S: 220 smtp.gmail.com ESMTP s19sm631546ign.4 - gsmtp
C: EHLO ks-dsatest-v41
S: 250-smtp.gmail.com at your service, [64.132.205.66]
S: 250-SIZE  35882577
S: 250-8BITMIME
S: 250-STARTTLS
S: 250-ENHANCEDSTATUSCODES
S: 250-PIPELINING
S: 250-CHUNKING
S: 250 SMTPUTF8
C: STARTTLS
S: 220 2.0.0 Ready to start TLS
C: QUIT
我的测试框上的SMTP邮件如下所示:

S: 220 smtp.gmail.com ESMTP vf11sm8649345igb.20 - gsmtp
C: EHLO ks-sayers-v60
S: 250-smtp.gmail.com at your service, [64.132.205.66]
S: 250-SIZE 35882577
S: 250-8BITMIME
S: 250-STARTTLS
S: 250-ENHANCEDSTATUSCODES
S: 250-PIPELINING
S: 250-CHUNKING
S: 250 SMTPUTF8
C: STARTTLS
S: 220 2.0.0 Ready to start TLS
C: EHLO ks-sayers-v60
S: 250-smtp.gmail.com at your service, [64.132.205.66]
S: 250-SIZE 35882577
S: 250-8BITMIME
S: 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
S: 250-ENHANCEDSTATUSCODES
S: 250-PIPELINING
S: 250-CHUNKING
S: 250 SMTPUTF8
S: 220 smtp.gmail.com ESMTP s19sm631546ign.4 - gsmtp
C: EHLO ks-dsatest-v41
S: 250-smtp.gmail.com at your service, [64.132.205.66]
S: 250-SIZE  35882577
S: 250-8BITMIME
S: 250-STARTTLS
S: 250-ENHANCEDSTATUSCODES
S: 250-PIPELINING
S: 250-CHUNKING
S: 250 SMTPUTF8
C: STARTTLS
S: 220 2.0.0 Ready to start TLS
C: QUIT
我在两个测试中使用相同的gmail用户和密码。我不知道为什么我的测试应用程序在测试盒上发送退出消息而不是EHLO

我们将非常感谢您提供的任何帮助或想法

RAD Studio XE4

印地10.6.0.4975

ssleay32.dll/libeay32.dll为v1.0.0g

测试代码:

void __fastcall TForm1::btnSendClick(TObject *Sender)
{
    IdLogFile1->Active = true;

    try
    {
        try
        {
            IdSMTP1->ConnectTimeout = 30000;
            IdSMTP1->Username = edtFrom->Text;
            IdSMTP1->Password = edtPassword->Text;
            IdMessage1->Recipients->Clear();
            IdMessage1->Recipients->Add();
            IdMessage1->Recipients->Items[0]->Address = edtTo->Text;

            IdSMTP1->Connect();
            if (IdSMTP1->Connected())
            {
                IdSMTP1->Send(IdMessage1);
            }
            LogSmtpSettings();
        }
        catch (Exception & e)
        {
            LogSmtpSettings();
            throw Exception(e.Message);
        }
    }
    __finally
    {
        IdLogFile1->Active = false;
    }
}
以下是TIdSMTP组件的属性:

Indy Version:        10.6.0.4975
Host:                smtp.gmail.com
Port:                587
HELO Name:           
Mail Agent:          
IOHandler:           TIdSSLIOHandlerSocketOpenSSL
Connection Timeout:  30000
Read Timeout:        -1
Authentication Type: Default
Validate Auth Login: True
Username:            's23ayers@gmail.com'
Use EHLO:            True
TLS:                 Explicit TLS
Use Nagle:           True
Use Pipelining:      True
Use VERP:            False
VERP Delimiters:     none
Intercept:           TIdLogFile
Intercept IsClient:  True
Supports TLS:        True
Last Command Result: Ready to start TLS

在收到
STARTTLS
successful应答后,测试盒立即发送
QUIT
命令,这意味着TLS握手失败
tidstp
在自身上调用
Disconnect()
,然后在代码中引发TLS异常,表示握手失败

此外,您正在使用较旧版本的Indy 10
TIdSMTP
于2014年年中更新,如果TLS握手失败,则不再发送
QUIT
。如果您使用的是10.6.0.4975,那么当前版本(在撰写本文时)是10.6.2.5339


现在,关于TLS握手失败的原因,大家都在猜测,因为您还没有提供任何关于您的设置的详细信息来诊断该问题。可能您没有为TLS正确配置
tidstp
。可能您的应用程序没有安装正确的SSL/TLS DLL。谁知道呢。请提供这些详细信息。

您的测试盒在收到
STARTTLS
成功回复后立即发送
QUIT
命令,这意味着TLS握手失败
tidstp
在自身上调用
Disconnect()
,然后在代码中引发TLS异常,表示握手失败

此外,您正在使用较旧版本的Indy 10
TIdSMTP
于2014年年中更新,如果TLS握手失败,则不再发送
QUIT
。如果您使用的是10.6.0.4975,那么当前版本(在撰写本文时)是10.6.2.5339


现在,关于TLS握手失败的原因,大家都在猜测,因为您还没有提供任何关于您的设置的详细信息来诊断该问题。可能您没有为TLS正确配置
tidstp
。可能您的应用程序没有安装正确的SSL/TLS DLL。谁知道呢。请提供这些详细信息。

我不知道这个库,但您需要检查证书错误吗?重新引发异常时,您应该使用
throw而不是
抛出异常(e.Message)。后者会丢失所有有用的信息。感谢您的输入!我不知道这个库,但是您需要检查证书错误吗?当重新抛出异常时,您应该使用
throw而不是
抛出异常(e.Message)。后者会丢失所有有用的信息。感谢您的输入!我今天要去旅行,我会在可能的时候把这些细节告诉你。我知道libeay32.dll和ssleay32.dll文件在这两个框中都是相同的。我捕获的异常通常是
连接正常关闭
,但偶尔会出现
套接字错误#10054连接被对等方重置。
。我已使用TIDSMP组件的属性编辑了我的问题。我注意到在我的dev box上成功测试后,
SupportsTLS==False
,当测试失败时,
SupportsTLS==True
SupportsTLS
仅当
EHLO
reply报告
STARTTLS
功能时才会返回True。您的开发盒将
SupportsTLS
报告为false,因为它成功地完成了
STARTTLS
握手并发出第二次
EHLO
,重置了
SupportsTLS
。由于TLS握手失败,您的测试盒无法发送第二个
EHLO
,因此在发送
STARTTLS
之前,您可以从初始
EHLO
中看到
SupportsTLS
值。谢谢,这很有意义。关于如何诊断TLS握手失败,有什么建议吗?我不确定从哪里找到问题的根源。在我看来,问题一定出在测试箱本身上。我能提供什么额外的细节?我今天正在旅行,我会在可能的时候把这些细节告诉你。我知道libeay32.dll和ssleay32.dll文件在这两个框中都是相同的。我捕获的异常通常是
连接正常关闭
,但偶尔会出现
套接字错误#10054连接被对等方重置。
。我已使用TIDSMP组件的属性编辑了我的问题。我注意到在我的dev box上成功测试后,
SupportsTLS==False
,当测试失败时,
SupportsTLS==True
SupportsTLS
仅当
EHLO
reply报告
STARTTLS
功能时才会返回True。您的开发盒将
SupportsTLS
报告为false,因为它成功地完成了
STARTTLS
握手并发出第二次
EHLO
,重置了
SupportsTLS
。由于TLS握手失败,您的测试盒无法发送第二个
EHLO
,因此您在之前看到了初始
EHLO
SupportsTLS