难!急!如何编程通过需要身份验证的smtp邮件服务器发送邮件?如www.163.net(100分)

  • 主题发起人 主题发起人 llgg
  • 开始时间 开始时间
L

llgg

Unregistered / Unconfirmed
GUEST, unregistred user!
如何编程通过需要身份验证的smtp邮件服务器发送邮件?如www.163.net
 
请来信,
lzmsoft@263.net
 
我在其它地方COPY一段源码过来,希望对你有所帮助

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Psock, NMsmtp, ComCtrls;

type
TForm1 = class(TForm)
NMSMTP1: TNMSMTP;
Button1: TButton;
Label1: 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 :='smtp.sohu.com';
nmsmtp1.Port :=25;
nmsmtp1.UserID :='linbch';//发信人的用户名,必须是真实的
nmsmtp1.ReportLevel :=1;
Nmsmtp1.TimeOut :=10000;
nmsmtp1.Connect ; ///连接
if AuthSucc=true then ////验证成功
begin
MailTo:=TStringList.Create;
MailTo.Add('cunmin1@163.net');
MailBody.Add('Hello it is a test');
nmsmtp1.PostMessage.FromAddress:='linbch@sohu.com'; //发信人的电子邮件地址
nmsmtp1.PostMessage.ToAddress :=MailTo;
nmsmtp1.PostMessage.Body:=MailBody;
nmsmtp1.PostMessage.Subject :='My test';
Mailto.Clear ;
//Mailto.Add('c:/a.txt');
//Mailto.Add('c:/b.txt');
//nmsmtp1.PostMessage.Attachments:=MailTo; 附件
MailTo.Free ;
MailBody.Free;
nmsmtp1.SendMail;
end;
end;
procedure TForm1.NMSMTP1Connect(Sender: TObject);
begin
//////连接成功,下面用户认证过程
label1.caption:=nmsmtp1.Status;
if nmsmtp1.ReplyNumber = 250 then
label1.caption:=nmsmtp1.Transaction('auth login'); //开始认证
if nmsmtp1.ReplyNumber =334 then //返回值为334,让你输入用BASE64编码后的用户名
label1.caption:=nmsmtp1.Transaction('YWFhYWE=');// 用户名aaaaa
if nmsmtp1.ReplyNumber =334 then // 返回值为334,让你输入用BASE64编码后的用户密码
label1.caption:=nmsmtp1.Transaction('MTIzNDU2'); //密码为123456
if nmsmtp1.ReplyNumber =235 then
begin
label1.caption:='successful';
AuthSucc:=true;
end;
//showmessage(label1.caption);
end;

procedure TForm1.NMSMTP1InvalidHost(var Handled: Boolean);
begin
label1.caption :='Invalid Host';
end;

procedure TForm1.NMSMTP1ConnectionFailed(Sender: TObject);
begin
label1.caption :='connect failed';
end;

procedure TForm1.NMSMTP1Status(Sender: TComponent; Status: String);
begin
label1.caption :=nmsmtp1.Status ;
end;

procedure TForm1.NMSMTP1SendStart(Sender: TObject);
begin
label1.Caption :='start send';
end;

procedure TForm1.NMSMTP1Success(Sender: TObject);
begin
label1.Caption:='send success!';
end;

end.
 
真可笑,它已经会使用了,还在这里装腔作势。
下面是它的来信及源文件。
--------------------------------------------------------------------------

=?GB2312?B?yrz+o78=?=
To: lzmsoft@263.net
Sender: 66891@163.com
Date: Wed, 20 Feb 2002 22:12:11 +0800
X-Priority: 3
X-Library: Indy 8.0.22

如何编程通过需要身份验证的smtp邮件服务器发送邮件?
POP3认证的详细步骤 代码?
详细代码,
OK?
Thanks a lot!!!!
 
什么叫做有帮助,这就是的[:)]
--->auth login
--<username
--<passwd

OK
急的话,抄上面的代码就可以了.完全的资料可以在RFC中找到.[:)]
 
感谢各位的帮助,我用pwolf的代码测试没有成功,在NMSMTP1.sendmail时报错,
系统提示“553 You are not authorized to send mail
as <MAIL FROM:<llgg@163.net>>,authentication is required”
请教该如何解决,谢谢。
 
我用上面的方法不能成功:
修改后以下,但不支持附件


unit SimpleMails;

interface

uses
Windows, Messages, SysUtils, Classes, Winsock, Psock;

type
TSimpleSMTP = class(TPowerSock)
private
FBody: string;
FPassword: string;
FSubject: string;
FUsername: string;
FMailFrom: string;
FMailTo: string;
procedure SetBody(const Value: string);
procedure SetMailFrom(const Value: string);
procedure SetMailTo(const Value: string);
procedure SetPassword(const Value: string);
procedure SetSubject(const Value: string);
procedure SetUsername(const Value: string);
procedure RaiseError(const Msg: string);
published
property MailTo: string read FMailTo write SetMailTo;
property MailFrom: string read FMailFrom write SetMailFrom;
property Subject: string read FSubject write SetSubject;
property Body: string read FBody write SetBody;
property Username: string read FUsername write SetUsername;
property Password: string read FPassword write SetPassword;

public
function Transaction(const CommandString: String): String; override;
public
function SendMail: Boolean;
constructor Create(AOwner: TComponent); override;
end;

function EncodeBase64(Source: string): string;

procedure Register;

implementation

const
BaseTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';

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;


// this function by Matjaz Bravc
function sak_GetInternetDate( const Date: TDateTime):string;
(* The date in RFC 822 conform string format *)

function int2str(value:integer; len:byte):string;
begin
result := IntToStr( value);
while length( result) < len do result := '0' + result;
end;

function GetTimeZoneBias:longint;
(* The offset to UTC/GMT in minutes of the local time zone *)
var tz_info: TTimeZoneInformation;
begin
case GetTimeZoneInformation(tz_info) of
1: result := tz_info.StandardBias+tz_info.Bias;
2: result := tz_info.DaylightBias+tz_info.Bias;
else
result := tz_info.DaylightBias+tz_info.Bias;
end;
end;

function GetTimeZone:string;
var bias: longint;
begin
bias := GetTimeZoneBias;
if bias = 0 then
begin
result := 'GMT';
end else
begin
if bias < 0 then
begin
result := '+' + int2str(abs(bias) div 60,2)+int2str(abs(bias) mod 60,2);
end else
begin
if bias > 0 then
begin
result := '-' + int2str(bias div 60,2)+int2str(bias mod 60,2);
end;
end;
end;
end;

var
d, m, y, w, h, mm, s, ms: word;
const
WeekDays: array [1..7] of string[3] = ('Sun','Mon','Tue','Wed',
'Thu','Fri','Sat');
Months: array [1..12] of string[3] = ('Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec');
begin
DecodeDate( date, y, m, d);
DecodeTime( date, h, mm, s, ms);
w := DayOfWeek( date);
Result := weekdays[w] + ', ' +
inttostr(d) + ' ' +
months[m] + ' ' +
inttostr(y) + ' ' +
int2str(h,2) + ':' +
int2str(mm,2) + ':' +
int2str(s,2) + ' ' +
GetTimeZone;
end;

function GetComputerName: string;
var
n: Cardinal;
begin
n:= MAX_COMPUTERNAME_LENGTH + 1;
SetLength(Result, n);
Windows.GetComputerName(PChar(Result), n);
SetLength(Result, n);
end;


{ TSimpleSMTP }
constructor TSimpleSMTP.Create(AOwner: TComponent);
begin
inherited;
Port:= 25;
end;


procedure TSimpleSMTP.SetBody(const Value: string);
begin
FBody := Value;
end;

procedure TSimpleSMTP.SetMailFrom(const Value: string);
begin
FMailFrom := Value;
end;

procedure TSimpleSMTP.SetMailTo(const Value: string);
begin
FMailTo := Value;
end;

procedure TSimpleSMTP.SetPassword(const Value: string);
begin
FPassword := Value;
end;

procedure TSimpleSMTP.SetSubject(const Value: string);
begin
FSubject := Value;
end;

procedure TSimpleSMTP.SetUsername(const Value: string);
begin
FUsername := Value;
end;



function TSimpleSMTP.Transaction(const CommandString: String): String;
var
S: string;
begin
Result:= inherited Transaction(CommandString);
S:= Result;
while Copy(S, 4, 1) = '-' do
begin
S:= Readln;
Result:= Result + S;
end;
end;


procedure TSimpleSMTP.RaiseError(const Msg: string);
begin
Raise Exception.Create(Msg);
end;

function TSimpleSMTP.SendMail: Boolean;
var
i: integer;
List: TStringList;
Header: string;
begin
Result:= False;
if not Connected then RaiseError(Host + ' not connect');

// read welcome ...
Header:= Readln;
while Copy(Header, 4, 1) = '-' do Header:= Self.Readln;

// say hello
Transaction('EHLO ' + GetComputerName);

// smtp server login
Transaction('AUTH LOGIN');
if ReplyNumber = 334 then
begin
Transaction(EncodeBase64(FUsername));
Transaction(EncodeBase64(FPassword));
if ReplyNumber>400 then RaiseError(TransactionReply);
end;

// mail from
Transaction(Format('MAIL FROM:<%s>', [FMailFrom]));
if ReplyNumber>400 then RaiseError(TransactionReply);

// send
List:= TStringList.Create;
List.Text:= StringReplace(FMailTo, ';', #13#10, [rfReplaceAll]);
for i:=0 to List.Count-1 do
begin
if List<>'' then
Transaction(Format('RCPT TO:<%s>', [List]));
end;

Transaction('DATA');
if ReplyNumber<>354 then RaiseError(TransactionReply);

Header:= Format(
'Date: %s'#13#10 +
'From: %s<%s>'#13#10 +
'Subject: %s'#13#10 +
'To: %s'#13#10#13#10,
[sak_GetInternetDate(now), FUserName, FMailFrom, FSubject, FMailTo]);

Transaction(Header + Body + #13#10'.'#13#10#13#10);
if ReplyNumber>400 then RaiseError(TransactionReply)
else Result:= True;

Transaction('QUIT')

end;


procedure Register;
begin
RegisterComponents('FastNet', [TSimpleSMTP]);
end;



end.
 
Idny中有smtpclient,
coolmail...
up
 
Idny中的例子,直接编译后就不好使。只能收邮件,发邮件时提示system busy.
不知道是什么原因。在98和2000下都这样。
 
学习,wang2855@etang.com
 
后退
顶部