2016-01-02 101 views
0

我已經嘗試了下面的代碼發送郵件,但它顯示連接正常關閉錯誤。我也嘗試過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 := '[email protected]'; 
    IdSMTP.Password := 'password'; 
    IdSMTP.Connect; 
    if IdSMTP.Authenticate then 
    begin 
     IdMessage := TIdMessage.Create(nil); 
     try 
     IdMessage.From.Name := 'User Name'; 
     IdMessage.From.Address := '[email protected]'; 
     IdMessage.Subject := 'E-mail subject'; 
     IdMessage.Body.Add('E-mail body.'); 

     IdEmailAddressItem := IdMessage.Recipients.Add; 
     IdEmailAddressItem.Address := '[email protected]'; 

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

enter image description here

回答

0

要使用STARTTLS,你需要

  1. 分配SSLIOHandler成分,如TIdSSLIOHandlerSocketOpenSSL,到TIdSMTP.IOHandler財產。如果尚未安裝在將運行應用程序的目標機器上,則必須將OpenSSL DLL部署到您的應用程序中。

  2. TIdSMTP.UseTLS屬性設置爲utUseExplicitTLS以啓用STARTTLS處理。確保TIdSMTP.UseEHLO爲真(默認情況下),以便TIdSMTP可以發現服務器是否支持STARTTLS

  3. 連接到端口587

試試這個:

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 := '[email protected]'; 
    IdSMTP.Password := 'password'; 
    IdSMTP.Connect; 
    if IdSMTP.Authenticate then 
    begin 
     IdMessage := TIdMessage.Create(nil); 
     try 
     IdMessage.From.Name := 'User Name'; 
     IdMessage.From.Address := '[email protected]'; 
     IdMessage.Subject := 'E-mail subject'; 
     IdMessage.Body.Add('E-mail body.'); 

     IdEmailAddressItem := IdMessage.Recipients.Add; 
     IdEmailAddressItem.Address := '[email protected]'; 

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

更新:上面的代碼是爲印10.如果您使用的是印9相反,有有些差異。

  1. OpenSSL組件被命名爲TIdSSLIOHandlerSocket

  2. TIdSMTP還不支持STARTTLS呢。您將不得不手動管理SSLIOHandler's PassThrough`屬性。

如果您連接到端口587進行顯式TLS,你必須設置PassThrough到真正開始,所以你連接到服務器加密,然後手動發送STARTTLS命令,並設置PassThrough假髮送任何前激活加密進一步的SMTP命令。

Procedure SendMail(); 
begin 
    IdSMTP1.Host := 'smtp.gmail.com'; 
    IdSMTP1.AuthenticationType := atLogin; 
    IdSMTP1.Port := 587; 
    IdSMTP1.Username := '[email protected]'; 
    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 := '[email protected]'; 
    IdMessage1.Recipients.EMailAddresses := '[email protected]'; 
    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 := '[email protected]'; 
    IdSMTP1.Password := 'password'; 
    IdSSLIOHandlerSocket1.PassThrough := False; 
    IdSMTP1.Connect; 
    try 
    IdMessage1.Body.Add('Test Message'); 
    IdMessage1.From.Address := '[email protected]'; 
    IdMessage1.Recipients.EMailAddresses := '[email protected]'; 
    IdMessage1.Subject := 'Hi'; 
    try 
     IdSMTP1.Send(IdMessage1); 
    except 
     ShowMessage('Error : email not send'); 
    end; 
    finally 
    IdSMTP1.Disconnect; 
    end; 
end; 
+0

謝謝,在這裏,我用delphi 7.0它不支持TIdSSLIOHandlerSocketOpenSSL DLL,這樣我就可以改變編碼爲這樣的。因爲我在這段代碼中得到了同樣的錯誤信息。 – Barani

+0

我在這裏使用Indy版本9.00.10。它顯示「無法加載SSL庫」。錯誤。端口:587,我也嘗試過端口465編碼,它也引發錯誤「連接關閉優雅」。 – Barani

+0

此外,我還附上了針對我的問題的組件詳情屏幕截圖。 – Barani

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 := '[email protected]'; 
      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    := '[email protected]'; 
       IdMessage1.Recipients.EMailAddresses := '[email protected]'; 
       IdMessage1.Subject := 'Hi'; 
       try 
       IdSMTP1.Send(IdMessage1); 
       except 
        ShowMessage('Error : email not send'); 
       end; 
       IdSMTP1.Disconnect; 
      end; 
    end; 
+0

我假設你正在使用你的Delphi 7附帶的(非常過時的)Indy版本?你真的需要升級到現代版的Indy。至於你有的版本,我已經更新了我的答案。 –

0

我幫:

發送郵件時,出現服務器錯誤:

'501 Syntactically invalid EHLO argument (s)' (error code 0x800CCC63).

如果計算機的名稱(運行Windows)包含無效字符,就會出現此錯誤:
(`` {_} '', Russian letters or spaces)
Control Panel> Network> Authentication
Have a look on naming files

應該通過改變。

還需要檢查通過指定的名稱:
Control Panel> Network> TCP

+0

作爲書面答案,此答案不反映OP要求的任何解決方案。通過編輯所需信息將其鏈接到問題或刪除答案來修改您的問題。 – ZF007