错误:连接正常关闭

时间:2016-01-02 13:40:12

标签: email smtp delphi-7

我已尝试使用以下代码发送邮件,但它显示连接正常关闭错误。我也尝试过587和465端口。身份验证还会引发“5.7.0必须首先发出STARTTLS命令.q27sm64805279pfi.83 - gsmtp”的错误。

uses
  IdSMTP, IdMessage, IdEMailAddress;

procedure SendSimpleMail;
var
  IdSMTP: TIdSMTP;
  IdMessage: TIdMessage;
  IdEmailAddressItem: TIdEmailAddressItem;
begin
  IdSMTP := TIdSMTP.Create(nil);
  try
    IdSMTP.Host := 'smtp.gmail.com';
    IdSMTP.Port := 25;   // or 587    //or 465
    IdSMTP.AuthType := satDefault;
    IdSMTP.Username := 'username@gmail.com';
    IdSMTP.Password := 'password';
    IdSMTP.Connect;
    if IdSMTP.Authenticate then
    begin
      IdMessage := TIdMessage.Create(nil);
      try
        IdMessage.From.Name := 'User Name';
        IdMessage.From.Address := 'username@gmail.com';
        IdMessage.Subject := 'E-mail subject';
        IdMessage.Body.Add('E-mail body.');

        IdEmailAddressItem := IdMessage.Recipients.Add;
        IdEmailAddressItem.Address := 'recipient@email.com';

        IdSMTP.Send(IdMessage);
      finally
        IdMessage.Free;
      end;
    end;
    IdSMTP.Disconnect;
  finally
    IdSMTP.Free;
  end;
end;

enter image description here

3 个答案:

答案 0 :(得分:2)

要使用STARTTLS,您需要

  1. TIdSSLIOHandlerSocketOpenSSL属性的SSLIOHandler组件分配给TIdSMTP.IOHandler。如果尚未在将运行应用程序的目标计算机上安装OpenSSL DLL,则必须在应用程序中部署OpenSSL DLL。

  2. TIdSMTP.UseTLS属性设置为utUseExplicitTLS以启用STARTTLS处理。确保TIdSMTP.UseEHLO为真(默认情况下是这样),以便TIdSMTP可以发现服务器是否支持STARTTLS

  3. 连接到端口587。

  4. 试试这个:

    uses
      IdSMTP, IdMessage, IdEMailAddress, IdSSLOpenSSL;
    
    procedure SendSimpleMail;
    var
      IdSMTP: TIdSMTP;
      IdMessage: TIdMessage;
      IdEmailAddressItem: TIdEmailAddressItem;
      IdSSL: TIdSSLIOHandlerSocketOpenSSL;
    begin
      IdSMTP := TIdSMTP.Create(nil);
      try
        IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdSMTP);
        IdSMTP.IOHandler := IdSSL;
        IdSMTP.UseTLS := utUseExplicitTLS;
        IdSMTP.Host := 'smtp.gmail.com';
        IdSMTP.Port := 587;
        IdSMTP.AuthType := satDefault;
        IdSMTP.Username := 'username@gmail.com';
        IdSMTP.Password := 'password';
        IdSMTP.Connect;
        if IdSMTP.Authenticate then
        begin
          IdMessage := TIdMessage.Create(nil);
          try
            IdMessage.From.Name := 'User Name';
            IdMessage.From.Address := 'username@gmail.com';
            IdMessage.Subject := 'E-mail subject';
            IdMessage.Body.Add('E-mail body.');
    
            IdEmailAddressItem := IdMessage.Recipients.Add;
            IdEmailAddressItem.Address := 'recipient@email.com';
    
            IdSMTP.Send(IdMessage);
          finally
            IdMessage.Free;
          end;
        end;
        IdSMTP.Disconnect;
      finally
        IdSMTP.Free;
      end;
    end;
    

    更新:上面的代码适用于Indy 10.如果您使用的是Indy 9,则存在一些差异。

    1. OpenSSL组件名为TIdSSLIOHandlerSocket

    2. TIdSMTP尚未支持STARTTLS。您必须手动管理SSLIOHandler's PassThrough`属性。

    3. 如果连接到端口587以获取显式TLS,则必须先将PassThrough设置为true,以便连接到未加密的服务器,然后手动发送STARTTLS命令并设置PassThrough在发送任何其他SMTP命令之前,为false以激活加密。

      Procedure SendMail();
      begin
        IdSMTP1.Host := 'smtp.gmail.com';
        IdSMTP1.AuthenticationType := atLogin;
        IdSMTP1.Port := 587;
        IdSMTP1.Username := 'user@gmail.com';
        IdSMTP1.Password := 'password';
        IdSSLIOHandlerSocket1.PassThrough := True;
        IdSMTP1.Connect;
        try
          IdSMTP1.SendCmd('STARTTLS', [220]);
          IdSSLIOHandlerSocket1.PassThrough := False;
          IdSMTP1.SendCmd('EHLO ' + IdSMTP1.LocalName);
          IdSMTP1.Authenticate;
          IdMessage1.Body.Add('Test Message');
          IdMessage1.From.Address := 'frommail@gmail.com';
          IdMessage1.Recipients.EMailAddresses := 'tomail@gmail.com';
          IdMessage1.Subject := 'Hi';
          try
            IdSMTP1.Send(IdMessage1);
          except
            ShowMessage('Error : email not send');
          end;
        finally
          IdSMTP1.Disconnect;
        end;
      end;
      

      如果您连接到端口465以获取隐式SSL,则在连接到服务器之前,您所要做的就是将PassThrough设置为false。在发送任何SMTP命令之前,连接最初将被加密,不需要STARTTLS

      Procedure SendMail();
      begin
        IdSMTP1.Host := 'smtp.gmail.com';
        IdSMTP1.AuthenticationType := atLogin;
        IdSMTP1.Port := 465;
        IdSMTP1.Username := 'user@gmail.com';
        IdSMTP1.Password := 'password';
        IdSSLIOHandlerSocket1.PassThrough := False;
        IdSMTP1.Connect;
        try
          IdMessage1.Body.Add('Test Message');
          IdMessage1.From.Address := 'frommail@gmail.com';
          IdMessage1.Recipients.EMailAddresses := 'tomail@gmail.com';
          IdMessage1.Subject := 'Hi';
          try
            IdSMTP1.Send(IdMessage1);
          except
            ShowMessage('Error : email not send');
          end;
        finally
          IdSMTP1.Disconnect;
        end;
      end;
      

答案 1 :(得分:0)

谢谢,我在这里使用delphi 7.0它将支持TIdSSLIOHandlerSocketOpenSSL dll,所以我可以像这样更改编码。由于我在此代码中收到相同的错误消息。

Procedure SendMail();
    var Resp : integer;
    begin
            IdSMTP1.Host :='smtp.gmail.com';
            IdSMTP1.AuthenticationType:= atLogin;
            IdSMTP1.Port := 587;
            IdSMTP1.Username := 'user@gmail.com';
            IdSMTP1.Password := 'password';
            IdSMTP1.Connect;
            if IdSMTP1.Connected then
            Begin
                Resp:= -1;
                Resp:= IdSMTP1.SendCmd('STARTTLS',Resp);
                IdMessage1.Body.Add('Tets Message');
                IdMessage1.From.Address              := 'frommail@gmail.com';
                IdMessage1.Recipients.EMailAddresses := 'tomail@gmail.com';
                IdMessage1.Subject  := 'Hi';
                try
                IdSMTP1.Send(IdMessage1);
                except
                  ShowMessage('Error : email not send');
                end;
                IdSMTP1.Disconnect;
            end;
    end;

答案 2 :(得分:0)

我得到了帮助:

发送邮件时,会发生服务器错误:

  

'501语法上无效的EHLO参数'(错误代码0x800CCC63)。

如果计算机名称(运行Windows)包含无效字符,则会出现此错误:
(`` {_} '', Russian letters or spaces)
Have a look on naming files

应通过以下方式更改:
Control Panel> Network> Authentication

还需要检查通过以下方式指定的名称:
Control Panel> Network> TCP