smtp如何通过用户名和密码的认证

解决方案 »

  1.   

    用 IdSMTP1  控件, delphi 自帶的
    http://www.marcocantu.com/code/md6htm/SendList.htmprocedure TMainForm.FormCreate(Sender: TObject);
    begin
      // load the list of addresses
      FileName := ChangeFileExt (Application.ExeName, '.txt');
      ListAddr.Items.LoadFromFile (FileName);
      ListLog.Items.Add ('Addresses: ' + IntToStr (
        ListAddr.Items.Count));
      // select the first item
      ListAddr.ItemIndex := 0;
    end;procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      // save the list of addresses
      ListAddr.Items.SaveToFile (FileName);
    end;const
      BccInMsg = 30;procedure TMainForm.BtnSendAllClick(Sender: TObject);
    var
      nItem: Integer;
      Res: Word;
    begin
      Res := MessageDlg ('Start sending from item ' +
          IntToStr (ListAddr.ItemIndex) + ' (' +
          ListAddr.Items [ListAddr.ItemIndex] + ')?'#13 +
          '(No starts form 0)',
          mtConfirmation,
          [mbYes, mbNo, mbCancel], 0);
      if Res = mrCancel then
        Exit;
      if Res = mrYes then
        nItem := ListAddr.ItemIndex
      else
        nItem := 0;  // connect
      Mail.Host := eServer.Text;
      Mail.UserID := eUserName.Text;
      if ePassword.Text <> '' then
      begin
        Mail.Password := ePassword.Text;
        Mail.AuthenticationType := atLogin;
      end;
      Mail.Connect;  // send the messages, one by one, prepending a custom message
      try
        // set the fixed part of the header
        MailMessage.From.Name := eFrom.Text;
        MailMessage.Subject := eSubject.Text;
        MailMessage.Body.SetText (
          reMessageText.Lines.GetText);
        MailMessage.Body.Insert (0, 'Hello');    while nItem < ListAddr.Items.Count do
        begin
          // show the current selection
          Application.ProcessMessages;
          ListAddr.ItemIndex := nItem;
          MailMessage.Body [0] := 'Hello ' + ListAddr.Items [nItem];
          MailMessage.Recipients.EMailAddresses := ListAddr.Items [nItem];
          Mail.Send(MailMessage);
          Inc (nItem);
        end;
      finally // we're done
        Mail.Disconnect;
      end;
    end;procedure TMainForm.BbtnAddToListClick(Sender: TObject);
    begin
      ListAddr.ItemIndex :=
        ListAddr.Items.Add (eName.Text);
    end;procedure TMainForm.BtnRemoveClick(Sender: TObject);
    begin
      // copy the item to the name edit box and remove it
      eName.Text := ListAddr.Items [ListAddr.ItemIndex];
      ListAddr.Items.Delete (ListAddr.ItemIndex);
    end;procedure TMainForm.BtnFindClick(Sender: TObject);
    var
      I: Integer;
    begin
      for I := 0 to ListAddr.Items.Count - 1 do
        if Pos (eName.Text, ListAddr.Items [I]) > 0 then
        begin
          ListAddr.ItemIndex := I;
          Break;
        end;
      Beep;
    end;procedure TMainForm.MailConnected(Sender: TObject);
    begin
      ListLog.Items.Add ('Connected to host');
    end;procedure TMainForm.MailDisconnected(Sender: TObject);
    begin
      ListLog.Items.Add ('Disconnected from host');
    end;procedure TMainForm.MailStatus(axSender: TObject;
      const axStatus: TIdStatus; const asStatusText: String);
    begin
      ListLog.Items.Add (asStatusText);
    end;procedure TMainForm.MailWorkBegin(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCountMax: Integer);
    begin
      ListLog.Items.Add ('Sending to: ' +
        MailMessage.Recipients.EMailAddresses);
    end;procedure TMainForm.MailWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
    begin
      ListLog.Items.Add ('Done');
    end;end.
      

  2.   

    這是另一份代碼, 也可以參考:procedure sendNewsLetter(an:Tstringlist; att1:Tstrings; Nachricht:Trichedit; 
    vonMail,Betreff,Priority,CT,SMTPServer,SMTPUsername,SMTPPass:String; 
    SMTPPort,SmtpAuthType:integer; PopServer,PopUser,PopPass:String; PopPort:integer); var IdMsgSend:TidMessage; SMTP:TidSmtp; POP:TidPop3; i:integer; s:string; 
    begin 
      IdMsgSend:=TidMessage.Create(nil); 
      SMTP:=TidSmtp.Create(nil); 
      POP:=TidPop3.create(nil); 
      IdMsgSend.Clear;     // Plain Text 
         with TIdText.Create(IdMsgSend.MessageParts, nil) do 
         begin 
           ContentType := 'text/plain'; 
           Body.Text := Nachricht.Text; 
         end;      // HTML Part 
         with TIdText.Create(IdMsgSend.MessageParts, nil) do 
         begin 
           ContentType := 'text/html'; 
           Body.Text := RtfToHtml('MetaHead',Nachricht); //Ben&ouml;tigt funktion um RTF zu HTML umzuwandeln 
            
         end;   with IdMsgSend do 
      begin 
        ContentType := CT; 
        From.Text := vonMail; 
        ReplyTo.EMailAddresses :=vonMail; 
        Subject := Betreff; 
        Priority := Priority ; 
        s:=''; 
        for i:=0 to an.Count-1 do 
        begin 
          s:=s+BccList.EMailAddresses+an.Strings[i]+';' 
        end; 
        BccList.EMailAddresses:=s; 
        ReceiptRecipient.Text:=''; 
      end;   if att1.Count>=1 then 
      begin 
        for i:=0 to att1.Count-1 do 
        begin 
          TIdAttachment.Create(IdMsgSend.MessageParts, att1.Strings[i] ); 
        end; 
      end; 
      IdMsgSend.ContentType :=CT ;   case SmtpAuthType of 
        0: SMTP.AuthenticationType := atNone; //Normal 
        1: SMTP.AuthenticationType := atLogin; //SMTPAuth 
        2: begin //AfterPop 
             SMTP.AuthenticationType := atNone; 
             POP.Host:=POPServer; 
             POP.Username:=POPUser; 
             POP.Password:=POPPass; 
             POP.Port:=POPPort; 
             POP.Connect(5); 
             POP.Disconnect; 
           end; 
        3: begin //afterPop+SMTPAuth 
             SMTP.AuthenticationType := atLogin; 
             POP.Host:=POPServer; 
             POP.Username:=POPUser; 
             POP.Password:=POPPass; 
             POP.Port:=POPPort; 
             POP.Connect(5); 
             POP.Disconnect; 
           end; 
      end; 
      SMTP.Username := SMTPUsername; 
      SMTP.Password := SMTPPass;   SMTP.Host := SMTPServer; 
      SMTP.Port := SMTPPort;   SMTP.Connect;   ShowMessage(IntToStr(IdMsgSend.MessageParts.Count)); 
      try 
        SMTP.Send(IdMsgSend); 
      finally 
        SMTP.Disconnect; 
      end; 
      IdMsgSend.free; 
      SMTP.free; 
      POP.free; 
    end;
      

  3.   


    //窗体上有一个BUTTON控件,一个LABEL控件,一个NMSMTP控件
    //带密码险证的邮件发送程序需要BASE64编码,DecodeBase64和 EncodeBase64
    //为解码和编码函数
    //在263、163和SOHU上都能发送成功
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls, Psock, NMsmtp, ComCtrls;type
    TForm1 = class(TForm)
      NMSMTP1: TNMSMTP;
      Button1: TButton;
        StatusBar1: TStatusBar;
        Edit1: TEdit;
        Label2: TLabel;
        Label3: TLabel;
        Edit2: TEdit;
        Label4: TLabel;
        Edit3: TEdit;
        Label5: TLabel;
        Edit4: TEdit;
        Label6: TLabel;
        Memo1: TMemo;
        Label7: TLabel;
        Edit5: TEdit;
        Label1: TLabel;
        Edit6: TEdit;
        Label8: TLabel;
      procedure Button1Click(Sender: TObject);
      procedure NMSMTP1Connect(Sender: TObject);
      procedure NMSMTP1InvalidHost(var Handled: Boolean);
      procedure NMSMTP1ConnectionFailed(Sender: TObject);
      procedure NMSMTP1Status(Sender: TComponent; Status: String);
      procedure NMSMTP1SendStart(Sender: TObject);
      procedure NMSMTP1Success(Sender: TObject);
    private
      { Private declarations }
    public
      { Public declarations }
    end;//BaseTable为BASE64码表
    const BaseTable:string='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';var
      Form1: TForm1;
      AuthSucc:boolean;// 是否需要密码验证
      function DecodeBase64(Source:string):string; //解码函数
      function FindInTable(CSource:char):integer; //
      function EncodeBase64(Source:string):string; //编码函数
    implementation
    {$R *.DFM}//
    function FindInTable(CSource:char):integer;
    begin
      result:=Pos(string(CSource),BaseTable)-1;
    end;
    ////function DecodeBase64(Source:string):string;
    var
      SrcLen,Times,i:integer;
      x1,x2,x3,x4,xt:byte;
    begin
      result:='';
      SrcLen:=Length(Source);
      Times:=SrcLen div 4;
      for i:=0 to Times-1 do
      begin
        x1:=FindInTable(Source[1+i*4]);
        x2:=FindInTable(Source[2+i*4]);
        x3:=FindInTable(Source[3+i*4]);
        x4:=FindInTable(Source[4+i*4]);
        x1:=x1 shl 2;
        xt:=x2 shr 4;
        x1:=x1 or xt;
        x2:=x2 shl 4;
        result:=result+chr(x1);
        if x3= 64 then break;
        xt:=x3 shr 2;
        x2:=x2 or xt;
        x3:=x3 shl 6;
        result:=result+chr(x2);
        if x4=64 then break;
        x3:=x3 or x4;
        result:=result+chr(x3);
      end;
    end;
    /////function EncodeBase64(Source:string):string;
    var
      Times,LenSrc,i:integer;
      x1,x2,x3,x4:char;
      xt:byte;
    begin
      result:='';
      LenSrc:=length(Source);
      if LenSrc mod 3 =0 then
        Times:=LenSrc div 3
      else
        Times:=LenSrc div 3 + 1;
      for i:=0 to times-1 do
      begin
        if LenSrc >= (3+i*3) then
        begin
          x1:=BaseTable[(ord(Source[1+i*3]) shr 2)+1];
          xt:=(ord(Source[1+i*3]) shl 4) and 48;
          xt:=xt or (ord(Source[2+i*3]) shr 4);
          x2:=BaseTable[xt+1];
          xt:=(Ord(Source[2+i*3]) shl 2) and 60;
          xt:=xt or (ord(Source[3+i*3]) shr 6);
          x3:=BaseTable[xt+1];
          xt:=(ord(Source[3+i*3]) and 63);
          x4:=BaseTable[xt+1];
        end
        else if LenSrc>=(2+i*3) then
        begin
          x1:=BaseTable[(ord(Source[1+i*3]) shr 2)+1];
          xt:=(ord(Source[1+i*3]) shl 4) and 48;
          xt:=xt or (ord(Source[2+i*3]) shr 4);
          x2:=BaseTable[xt+1];
          xt:=(ord(Source[2+i*3]) shl 2) and 60;
          x3:=BaseTable[xt+1];
          x4:='=';
        end else
        begin
          x1:=BaseTable[(ord(Source[1+i*3]) shr 2)+1];
          xt:=(ord(Source[1+i*3]) shl 4) and 48;
          x2:=BaseTable[xt+1];
          x3:='=';
          x4:='=';
        end;
        result:=result+x1+x2+x3+x4;
      end;
    end;//////////
    procedure TForm1.Button1Click(Sender: TObject);
    //var MailTo,MailBody:TStringList;
    begin
      Nmsmtp1.Host :=Edit1.Text;
      nmsmtp1.Port :=25;
      nmsmtp1.UserID :=Edit2.Text;//发信人的用户名,必须是真实的
      nmsmtp1.ReportLevel :=1;
      Nmsmtp1.TimeOut :=10000;
      nmsmtp1.Connect ; ///连接
      if AuthSucc=true then ////验证成功
      begin
        nmsmtp1.PostMessage.FromAddress:=Edit4.Text; //发信人的电子邮件地址
        nmsmtp1.PostMessage.ToAddress.Text :=Edit5.Text;
        nmsmtp1.PostMessage.Body.Text:=Memo1.Text;
        nmsmtp1.PostMessage.Subject :=Edit6.Text;
        nmsmtp1.SendMail;
      end;
    end;procedure TForm1.NMSMTP1Connect(Sender: TObject);
    begin
      //////连接成功,下面用户认证过程
      StatusBar1.SimpleText:=nmsmtp1.Status;
      if nmsmtp1.ReplyNumber = 250 then
        StatusBar1.SimpleText:=nmsmtp1.Transaction('auth login'); //开始认证
      if nmsmtp1.ReplyNumber =334 then //返回值为334,让你输入用BASE64编码后的用户名
        StatusBar1.SimpleText:=nmsmtp1.Transaction(EncodeBase64(Edit2.Text));
      if nmsmtp1.ReplyNumber =334 then // 返回值为334,让你输入用BASE64编码后的用户密码
        StatusBar1.SimpleText:=nmsmtp1.Transaction(EncodeBase64(Edit3.Text));
      if nmsmtp1.ReplyNumber =235 then
      begin
        StatusBar1.SimpleText:='successful';
        AuthSucc:=true;
      end;
    end;procedure TForm1.NMSMTP1InvalidHost(var Handled: Boolean);
    begin
      StatusBar1.SimpleText :='Invalid Host';
    end;
    procedure TForm1.NMSMTP1ConnectionFailed(Sender: TObject);
    begin
      StatusBar1.SimpleText :='connect failed';
    end;
    procedure TForm1.NMSMTP1Status(Sender: TComponent; Status: String);
    begin
      StatusBar1.SimpleText :=nmsmtp1.Status ;
    end;
    procedure TForm1.NMSMTP1SendStart(Sender: TObject);
    begin
      StatusBar1.SimpleText :='start send';
    end;
    procedure TForm1.NMSMTP1Success(Sender: TObject);
    begin
      StatusBar1.SimpleText:='send success!';
    end;end.
      
      

  4.   

    To kuki84(天道酬勤):
       我使用idtcpClient控件用该控件的SendCmd方法代替NMSmtp的Transaction方法,以前几步都正确,为什么到了发送密码的时候就不成功了呢