- //---------------------------------------------------------------------------
- #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();
- }
- //---------------------------------------------------------------------------
基于TClientSocket简单模拟需要验证的SMTP邮件发送附件(C++Builder)
最新推荐文章于 2023-01-25 19:40:13 发布