c:ehlo hostname
s:250-smtp.263.net
250-pipelining
250-size 10240000
250-etrn
250-auth login
250-8bitmime
以上是与邮件服务器连接,即nmsmtp1->connect,以下是连接后的验证:
c:auth login
s:334VXNlcm5hbWU6(username
c:b(你的用户名转换成base64码)
s:334UGFzc3dvcmQ6(password
c:x(你的密码转换成base64码)
nmsmtp有个transaction方法,在onconnect事件中加入验证过程,
nmsmtp1->transaction("auth login"),返回值是334表示通过,可以继续下面的
nmsmtp1->transaction(你的用户名转换成base64码)
nmsmtp1->transaction(你的密码转换成base64码)
如果返回235表示验证成功,你就可以发邮件了
//这是我写的一个演示程序,
//窗体上有一个BUTTON控件,一个LABEL控件,一个NMSMTP控件
//带密码险证的邮件发送程序需要BASE64编码,DecodeBase64和 EncodeBase64
//为解码和编码函数
//在263、163和SOHU上都能发送成功
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.
上面是用DELPHI写的,发送部分基本是一样的都是在CONNECT中验证,下面是C++ BUILDER写的BASE64编码解码程序,请多多指教:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
const AnsiString BaseTable="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
byte FindInTable(byte c);
//---------------------------------------------------------------------------
#pragma package(smart_init)
////
AnsiString DecodeBase64(AnsiString Source)
{
byte x1,x2,x3,x4,xt;
int SrcLen,Times,i;
AnsiString Result;
Result="";
SrcLen=Source.Length();
Times=SrcLen / 4;
for(i=0;i<Times;i++)
{
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<<=2;
xt=x2>>4;
x1=x1 | xt;
Result+=char(x1);
//ShowMessage(char(x1));
x2<<=4;
if (x3==64) break;//x3 不是"="号
xt=x3>>2;
x2=x2 | xt;
x3<<=6;
Result+=char(x2);
if (x4==64) break;
x3=x3 | x4;
Result+=char(x3);
}
return Result;
}
//////////
AnsiString EncodeBase64(AnsiString Source)
{
int Times,LenSrc,i;
unsigned char x1,x2,x3,x4,xt,xt1;
AnsiString Result;
Result="";
LenSrc=Source.Length();
if (LenSrc % 3==0) Times=LenSrc/3;
else
Times=LenSrc/3+1;
for(i=0;i<Times;i++)
{
if (LenSrc>=(3*i+3))
{
xt=Source[1+i*3];
xt>>=2;
x1=BaseTable[xt+1];
xt=Source[1+i*3];
xt<<=4;
xt&=48;
xt1=Source[2+i*3];
xt1>>=4;
xt|=xt1;
x2=BaseTable[xt+1];
xt=Source[2+i*3];
xt<<=2;
xt&=60;
xt1=Source[3+i*3];
xt1>>=6;
xt|=xt1;
x3=BaseTable[xt+1];
xt=Source[3+i*3] ;
xt&=63;
x4=BaseTable[xt+1];
}
else
if (LenSrc>=3*i+2)
{
xt=Source[1+i*3];
xt>>=2;
x1=BaseTable[xt+1];
xt=Source[1+i*3];
xt<<=4;
xt&=48;
xt1=Source[2+i*3];
xt1>>=4;
xt|=xt1;
x2=BaseTable[xt+1];
xt=Source[2+i*3];
xt<<=2;
xt&= 60;
x3=BaseTable[xt+1];
x4='=';
}
else
{
xt=Source[1+i*3];
xt>>=2;
x1=BaseTable[xt+1];
xt=Source[1+i*3] ;
xt<<=4;
xt&=48;
x2=BaseTable[xt+1];
x3='=';
x4='=';
}
Result+=char(x1);
Result+=char(x2);
Result+=char(x3);
Result+=char(x4);
}
return Result;
}
///////////
byte FindInTable(byte c)
{
//ShowMessage(char(c));
return BaseTable.Pos(char(c))-1;
}