您的位置:首页 > 编程语言 > C语言/C++

基于TClientSocket简单模拟需要验证的SMTP邮件发送附件(C++Builder)

2008-09-23 12:49 513 查看
原文:http://blog.csdn.net/unsigned/archive/2008/09/22/2961051.aspx
基于TClientSocket简单模拟需要验证的SMTP邮件发送附件(C++Builder)


//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <dos.h>
#include "Mail.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
//#define BUFFER_SIZE 0x0348 /* 840 Max Stack Size 64kb*/
#define BUFFER_SIZE 0x1DE5 /* 7653 */
#define BUFFER_SIZE_3 BUFFER_SIZE*(57+0)
#define BUFFER_SIZE_4 BUFFER_SIZE*(76+2)

AnsiString EncodeBase64Char(char Value[],int Len)
{

char Buffer[BUFFER_SIZE_4+1];

char Base64Table[64]={'A','B','C','D','E','F','G','H',
'I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X',
'Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n',
'o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3',
'4','5','6','7','8','9','+','/'
};
for(int i=0;i<Len;i+=3)
{
//____________________________________________________
//  ↓☆☆☆☆↓
//00111111111111111111111111
//  ├→ 1  ←┤├→ 2  ←┤├→ 3  ←┤
//  876543218765432187654321
//00111111
//----------------------------------------------------
Buffer[i/57*2+i/3+i+0]=Base64Table[(Value[i]>>2)&0x003f];
//____________________________________________________
//        ↓☆☆☆☆↓
//00111111111111111111111111
//  ├→ 1  ←┤├→ 2  ←┤├→ 3  ←┤
//  876543218765432187654321
//      00111111
//----------------------------------------------------
Buffer[i/57*2+i/3+i+1]=Base64Table[((Value[i]&0x0003)<<4)|
((Value[i+1]>>4)&0x000f)];
//____________________________________________________
//              ↓☆☆☆☆↓
//00111111111111111111111111
//  ├→ 1  ←┤├→ 2  ←┤├→ 3  ←┤
//  876543218765432187654321
//            00111111
//----------------------------------------------------
Buffer[i/57*2+i/3+i+2]=Base64Table[(((Value[i+1]&0x000f)<<2))|
((Value[i+2]>>6)&0x0003)];
//____________________________________________________
//                    ↓☆☆☆☆↓
//00111111111111111111111111
//  ├→ 1  ←┤├→ 2  ←┤├→ 3  ←┤
//  876543218765432187654321
//                  00111111
//----------------------------------------------------
Buffer[i/57*2+i/3+i+3]=Base64Table[Value[i+2]&0x003f];

Buffer[i/57*2+i/3+i+4]='/0';

if((i+3)%57==0)
{
Buffer[i/57*2+i/3+i+4]='/r';
Buffer[i/57*2+i/3+i+5]='/n';
}
}

Buffer[BUFFER_SIZE_4]='/0';

return AnsiString(Buffer);
}
void EncodeBase64File(AnsiString FileName,TStream *DestStream)
{
__int64 i;
int sLen;
int ssLen;
AnsiString DestString;
char Buffer[BUFFER_SIZE_3];
TFileStream *SourceStream;
SourceStream=new TFileStream(FileName,fmOpenRead|fmShareDenyWrite);
try
{
for(i=0;i<SourceStream->Size;i+=BUFFER_SIZE_3)
{
ssLen=SourceStream->Size-i;
if(ssLen>BUFFER_SIZE_3)
ssLen=BUFFER_SIZE_3;
SourceStream->ReadBuffer(&Buffer,ssLen);
sLen=ssLen;
switch(ssLen%3)
{
case 2:
Buffer[ssLen+1]='/0';
sLen+=1;
case 1:
Buffer[ssLen+0]='/0';
sLen+=1;
}
DestString=EncodeBase64Char(Buffer,sLen);
sLen=DestString.Length();
DestStream->Seek(0,soFromEnd);
DestStream->WriteBuffer(DestString.c_str(),sLen);
ssLen=4;
if(DestString.c_str()[sLen]=='/n')
ssLen+=2;
}
switch(SourceStream->Size%3)
{
case 1:
DestString="==";
DestStream->Seek(2-ssLen,soFromEnd);
DestStream->WriteBuffer(DestString.c_str(),DestString.Length());
break;
case 2:
DestString="=";
DestStream->Seek(3-ssLen,soFromEnd);
DestStream->WriteBuffer(DestString.c_str(),DestString.Length());
}
}
__finally
{
SourceStream->Free();
}
}
AnsiString Base64EnTable(int so)
{
if(so>=0&&so<=25)
return AnsiString((char)(so+65));
if(so>=26&&so<=51)
return AnsiString((char)(so+71));
if(so>=52&&so<=61)
return AnsiString((char)(so-4));
if(so==62)
return "+";
return "/";
}

AnsiString EncodeBase64(AnsiString source)
{
AnsiString dest="",addtail="";
if(source.Length()==0)
return "";
for(int j=0;j<source.Length();j+=3)
{
int k,k1,l,l1,m,m1,n,mn;
k=source.c_str()[j];
j+1>source.Length()?l=0:l=source.c_str()[j+1];
j+2>source.Length()?m=0:m=source.c_str()[j+2];

k&=0xFF; //read a unsigned char
l&=0xFF;
m&=0xFF;

mn=k<<16; //make three characters to a 4-bit number
mn+=l<<8;
mn+=m;

k1=mn>>18;//the first character's index in base64table
k1&=0x3F;
l1=mn>>12;//the second
l1&=0x3F;
m1=mn>>6; //the third
m1&=0x3F;
n=mn&0x3F;//the fourth

dest+=Base64EnTable(k1)+Base64EnTable(l1)+
Base64EnTable(m1)+Base64EnTable(n);
if((j+3)%57==0)
dest+="/r/n";
}
switch(source.Length()%3)
{
case 1:
dest=dest.SubString(1,dest.Length()-2);
dest+="==";
break;
case 2:
dest=dest.SubString(1,dest.Length()-1);
dest+="=";
break;
}
return dest;
}

void __fastcall TForm1::AddClick(TObject *Sender)
{
if(OpenDialog1->Execute())
{
Attach->Items->AddStrings(OpenDialog1->Files);
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::AttachClick(TObject *Sender)
{
if(Attach->SelCount>0)
Del->Enabled=true;
else
Del->Enabled=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DelClick(TObject *Sender)
{
Attach->DeleteSelected();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
AnsiString t=Socket->ReceiveText();
AnsiString SendMsg;
Mess->Lines->Add(t.SubString(1,t.Length()-2));
switch(ppp)
{
case 0:
ppp++;
SendMsg="EHLO "+SMTPSERVER->Text.Trim()+"/r/n";
if(!AUTH->Checked)
{
ppp+=3;
SendMsg="HELO "+SMTPSERVER->Text.Trim()+"/r/n";
}
Mess->Lines->Add(SendMsg.SubString(1,SendMsg.Length()-2));
Socket->SendText(SendMsg);
break;
case 1:
ppp++;
SendMsg="AUTH LOGIN/r/n";
Mess->Lines->Add(SendMsg.SubString(1,SendMsg.Length()-2));
Socket->SendText(SendMsg);
break;
case 2:
ppp++;
SendMsg=EncodeBase64(USERID->Text)+"/r/n";
Mess->Lines->Add(SendMsg.SubString(1,SendMsg.Length()-2));
Socket->SendText(SendMsg);
break;
case 3:
ppp++;
SendMsg=EncodeBase64(PWD->Text)+"/r/n";
Mess->Lines->Add(SendMsg.SubString(1,SendMsg.Length()-2));
Socket->SendText(SendMsg);
break;
case 4:
ppp++;
SendMsg="MAIL FROM: <"+FROM->Text.Trim()+">/r/n";
Mess->Lines->Add(SendMsg.SubString(1,SendMsg.Length()-2));
Socket->SendText(SendMsg);
break;
case 5:
{ppp++;
SendMsg="RCPT TO: <"+TO->Text.Trim()+">/r/n";
if(TOCC->Text.Trim().Length()>0)
SendMsg+="RCPT TO: <"+TOCC->Text.Trim()+">/r/n";
Mess->Lines->Add(SendMsg.SubString(1,SendMsg.Length()-2));
Socket->SendText(SendMsg);
}
break;
case 3+3:
ppp++;
SendMsg="DATA/r/n";
Mess->Lines->Add(SendMsg.SubString(1,SendMsg.Length()-2));
Socket->SendText(SendMsg);
break;
case 4+3:
{
TMemoryStream *memstr;
ppp++;
Mess->Lines->Add("Sending Data ...");
memstr=new TMemoryStream();
try
{
AnsiString sendtext=AnsiString("Message-ID: <000e01c26603$6f0e7a30$0a00a8c0@yj01>")+
"/r/nFrom: /""+Edit1->Text.Trim()+"/" <"+FROM->Text.Trim()+">/r/n"+
"To: <"+TO->Text.Trim()+">/r/n";
if(TOCC->Text.Trim()!="")
sendtext+=AnsiString("Cc: <"+TOCC->Text.Trim()+">/r/n");
SYSTEMTIME t;
GetLocalTime(&t);
AnsiString tday[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"},
tmon[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
if(SUBJECT->Text.Trim().Length()>0)
sendtext+="Subject: =?gb2312?B?"+EncodeBase64(SUBJECT->Text.Trim())+"?=/r/n";
else
sendtext+="Subject:/r/n";
sendtext+="Date: "+tday[t.wDayOfWeek]+Now().FormatString(", dd ")+tmon[t.wMonth-1]+Now().FormatString(" yyyy hh:mm:ss +0800")+"/r/n"+
"MIME-Version: 1.0/r/n"
"Content-Type: multipart/mixed;/r/n"
" boundary=/"----=_NextPart_000_000A_01C26646.7D0E7AC0/"/r/n"+
"X-Priority: 3/r/n"+
"X-MSMail-Priority: Normal/r/n"+
"X-Mailer: Morncolorsoft E_Mail Sender 1.00.0000.0000/r/n"+
"X-Mime: Morncolorsoft Mailer Inside V1.00.0000.0000/r/n/r/n"+
"This is a multi-part message in MIME format./r/n/r/n"+
"------=_NextPart_000_000A_01C26646.7D0E7AC0/r/n"+
"Content-Type: multipart/alternative;/r/n"+
" boundary=/"----=_NextPart_001_000B_01C26646.7D0E7AC0/"/r/n/r/n/r/n"+
"------=_NextPart_001_000B_01C26646.7D0E7AC0/r/n"+
"Content-Type: text/plain;/r/n"+
" charset=/"gb2312/"/r/n"+
"Content-Transfer-Encoding: base64/r/n/r/n"+
EncodeBase64(Body->Text)+"/r/n/r/n"+
"------=_NextPart_001_000B_01C26646.7D0E7AC0/r/n"+
"Content-Type: text/html;/r/n"+
" charset=/"gb2312/"/r/n"+
"Content-Transfer-Encoding: base64/r/n/r/n"+
EncodeBase64(AnsiString("<!DOCTYPE HTML PUBLIC /"-//W3C//DTD HTML 4.0 Transitional//EN/">/r/n")+
"<HTML><HEAD>/r/n"+
"<META http-equiv=Content-Type content=/"text/html; charset=gb2312/">/r/n"+
"<META content=/"MSHTML 6.00.2600.0/" name=GENERATOR>/r/n"+
"<STYLE></STYLE>/r/n"+
"</HEAD>/r/n"+
"<BODY bgColor=#ffffff>/r/n"+
"<DIV><FONT size=2><PRE>"+Body->Text+"</PRE></FONT></DIV></BODY></HTML>")+
"/r/n------=_NextPart_001_000B_01C26646.7D0E7AC0--/r/n";
if(Attach->Count>0)
{
memstr->WriteBuffer(sendtext.c_str(),sendtext.Length());
for(int kk=0;kk<Attach->Count;kk++)
if(FileExists(Attach->Items->Strings[kk]))
{
AnsiString sendtextt=AnsiString("/r/n------=_NextPart_000_000A_01C26646.7D0E7AC0/r/n")+
"Content-Type: application/octet-stream;/r/n"+
" name=/""+ExtractFileName(Attach->Items->Strings[kk])+"/"/r/n"+
"Content-Transfer-Encoding: base64/r/n"+
"Content-Disposition: attachment;/r/n"+
" filename=/""+ExtractFileName(Attach->Items->Strings[kk])+"/"/r/n/r/n";
memstr->Seek(0,soFromEnd);
memstr->WriteBuffer(sendtextt.c_str(),sendtextt.Length());
EncodeBase64File(Attach->Items->Strings[kk],memstr);
memstr->Seek(0,soFromEnd);
AnsiString ttt="/r/n";
memstr->WriteBuffer(ttt.c_str(),ttt.Length());
}
AnsiString sendtexttt="/r/n------=_NextPart_000_000A_01C26646.7D0E7AC0--/r/n/r/n./r/n";
memstr->Seek(0,soFromEnd);
memstr->WriteBuffer(sendtexttt.c_str(),sendtexttt.Length());
memstr->Seek(0,soFromBeginning);
//Mess->Lines->LoadFromStream(memstr);
Socket->SendStream(memstr);
}
else
Socket->SendText(sendtext+"/r/n./r/n");
}
catch(...)
{
memstr->Free();
}
break;
}
case 5+3:
ppp++;
SendMsg="QUIT/r/n";
Mess->Lines->Add(SendMsg.SubString(1,SendMsg.Length()-2));
Socket->SendText(SendMsg);
break;
case 6+3:
ppp=-1;
break;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SendClick(TObject *Sender)
{
if(SMTPSERVER->Text.Trim()=="")
return;
if(PORT->Text.Trim()=="")
return;
if(TO->Text.Trim()=="")
return;
int port=StrToInt(PORT->Text.Trim());
if(port==0)
port=25;
Send->Enabled=false;
ppp=0;
ClientSocket1->Host=SMTPSERVER->Text.Trim();
ClientSocket1->Port=port;
ClientSocket1->Open();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Disconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
Send->Enabled=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::GetClick(TObject *Sender)
{
/* TTime t;
TDate d;
t=Now();
d=Now();
ShowMessage(t.DayOfWeek());

//"Date: Wed, 25 Sep 2002 08:17:50 +0800/r/n"+
ShowMessage( d.FormatString("DDD, dd MMM yyyy hh:mm:ss +0800"));
*/
AnsiString ss="";
for(int i=0;i<Body->Text.Length();i++)
{
ss+=IntToStr((int)Body->Text.c_str()[i])+" ";
}
Mess->Text=ss;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ClientSocket1Error(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
Send->Enabled=true;
ErrorCode=0;
Socket->Close();
}
//---------------------------------------------------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: