使用smtp发送邮件(源码)

    技术2022-05-11  100

     

    源文件:

    #include <vcl.h>#pragma hdrstop

    #include "sendmail.h"#include "mmsystem.h"

    #pragma package(smart_init)

    struct RecvEmailInfo{    AnsiString     strSubject, strFrom, strTo, strContent, strCmdDate, strCmdNum;    int            nRecNum, nSendCount;    TList         *AttachList;};

    struct AttachInfo{    AnsiString     FileName;    int            Length;    BYTE          *Content;};__fastcall TSendMailThread::TSendMailThread(bool CreateSuspended,int sleeptime ) : TThread(CreateSuspended){ Ftime           = sleeptime;    FreeOnTerminate = true;    nSendFlag       = -1;    nCommandKind    = 0;    strBoundary     = "----Mailor_of_qurqur.China----";

        RecvEmailList= new TList;

        /*TMemoryStream *ms = new TMemoryStream();    ms->LoadFromFile( "d://test.txt" );    RecvEmailInfo * pREI;    AttachInfo * pAI;    for( int i = 0; i < 5; i ++ )    {        pAI = new AttachInfo;        pREI = new RecvEmailInfo;        pAI->FileName = "test.txt";        pAI->Length   = ms->Size;        pAI->Content = new BYTE[ ms->Size ];        ms->Position = 0;        ms->ReadBuffer( pAI->Content, ms->Size );        pREI->AttachList = new TList;        pREI->AttachList->Add( pAI );        pREI->strSubject = "humor";        pREI->strFrom = "qurqur@163.net";        pREI->strTo   = "qurqur@163.net;        pREI->strContent = "test";        pREI->nSendCount = 5;        RecvEmailList->Add( pREI );    }    delete ms;*/}void __fastcall TSendMailThread::Execute(){    WORD wVersionRequested;    WSADATA wsaData;    int err;

        wVersionRequested = MAKEWORD( 2, 2 );

        err = WSAStartup( wVersionRequested, &wsaData );    if ( err != 0 )    {        // Tell the user that we could not find a usable WinSock DLL.        return;    }    if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )    {        // Tell the user that we could not find a usable WinSock DLL.        WSACleanup( );        return;    }     while( !Terminated )    {        if( !bCanSendEmail )        {            Sleep( Ftime );            continue;        }        SendDeal();        Sleep( 10 );    }}int __fastcall TSendMailThread::InitSocket(){    smtpclient = socket( AF_INET, SOCK_STREAM, 0 );    if( smtpclient == INVALID_SOCKET )    {        return -1;    }    HOSTENT* hostinfo = gethostbyname( strSMTPServer.c_str() );    if( hostinfo == NULL )        return -1;

        struct sockaddr_in server;    server.sin_family = AF_INET;    server.sin_port = htons( nSMTPPort );    memcpy( &server.sin_addr, *hostinfo->h_addr_list, sizeof( server.sin_addr ) );    int rval = connect( smtpclient, ( struct sockaddr* )&server, sizeof( server ) );    if( rval == SOCKET_ERROR )    {       // rval = WSAGetLastError();        return -1;    }    return 0;}void __fastcall TSendMailThread::SendDeal(){    unsigned int new_time;    char aa[ 8200 ];    int err, len;    switch( nSendFlag )    {    case -1 :       if( HaveEmail() )       {           err = InitSocket();           if( err == -1 )           {               nSendFlag = 1;

                  strcpy( buf, "error" );

                  nCommandKind = 9;

               }           else           {               strBeginTime = Now().FormatString( "yyyy-mm-dd hh:mm:ss" );               nSendFlag = 0;               nCommandKind = 0;           }       }    break;    case 0 :        len = recv( smtpclient, buf, 8192, 0 );        if( len == SOCKET_ERROR )//err        {            nSendFlag = 1;

                nCommandKind = 9;            break;        }        buf[ len ] = 0;        nSendFlag = 1;    break;    case 1 :        switch( nCommandKind )        {        case 0 :            if( AnsiString( buf ).AnsiPos( "220" ) != 0 )            {                //连接成功,发送HELO                strcpy( buf, "helo " );                strcat( buf, strSMTPServer.c_str() );                strcat( buf, "/r/n" );                if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                {                    nCommandKind = 9;

                        strcpy( buf, "error" );

                        break;                }                nSendFlag = 0;                nCommandKind = 2;            }            else            {                                    nCommandKind = 9;

                        strcpy( buf, "error" );;            }        break;        case 2 ://受到HELO应答,身份验证            if( AnsiString( buf ).AnsiPos( "250" ) != 0 )            {                strcpy( buf, "auth login" );                strcat( buf, "/r/n" );                if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                {                    nCommandKind = 9;

                        strcpy( buf, "error" );                    break;                }                nSendFlag = 0;                nCommandKind = 3;            }            else            {                    nCommandKind = 9;

                        strcpy( buf, "error" );            }        break;        case 3 ://收到应答 用户名           if( AnsiString( buf ).AnsiPos( "334" ) != 0 )           {               strcpy( buf, Encode_Name.c_str() );               strcat( buf, "/r/n" );               if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )               {                    nCommandKind = 9;

                        strcpy( buf, "error" );                   break;               }               nSendFlag = 0;               nCommandKind = 4;          }          else          {              strcpy( buf, "mail from: " );              strcat( buf, FromAddress.c_str() );              strcat( buf, "/r/n" );              if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )              {                    nCommandKind = 9;

                        strcpy( buf, "error" );

                      break;              }              nSendFlag = 0;              nCommandKind = 6;//no auth          }        break;        case 4 ://受到应答 密码            if( AnsiString( buf ).AnsiPos( "334" ) != 0 )            {                strcpy( buf, Encode_Key.c_str() );                strcat( buf, "/r/n" );                if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                {                    nCommandKind = 9;

                        strcpy( buf, "error" );                    break;                }                nSendFlag = 0;                nCommandKind = 5;            }            else            {                    nCommandKind = 9;

                        strcpy( buf, "error" );            }        break;        case 5 ://应答  MAIL FROM            if( AnsiString( buf ).AnsiPos( "235" ) != 0 )            {                strcpy( buf, "mail from: " );                strcat( buf, FromAddress.c_str() );                strcat( buf, "/r/n" );                if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                {                    nCommandKind = 9;

                        strcpy( buf, "error" );                    break;                }                nSendFlag = 0;                nCommandKind = 6;            }            else            {                    nCommandKind = 9;

                        strcpy( buf, "error" );            }        break;        case 6 ://应答  RCPT TO            if( AnsiString( buf ).AnsiPos( "250" ) != 0 )            {                strcpy( buf, "rcpt to: " );                strcat( buf, recv_temp->strTo.c_str() );                strcat( buf, "/r/n" );                if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                {                    nCommandKind = 9;

                        strcpy( buf, "error" );                    break;                }                nSendFlag = 0;                nCommandKind = 7;            }            else            {                    nCommandKind = 9;

                        strcpy( buf, "error" );            }        break;        case 7 ://应答  DATA            if( AnsiString( buf ).AnsiPos( "250" )!=0 )            {                strcpy( buf, "data/r/n" );                strcat( buf, "/r/n" );                if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                {                    nCommandKind = 9;

                        strcpy( buf, "error" );                    break;                }                nSendFlag = 0;                nCommandKind = 8;            }            else            {                    nCommandKind = 9;

                        strcpy( buf, "error" );            }        break;        case 8 ://应答  内容            if( AnsiString( buf ).AnsiPos( "354" )!=0 )            {                strcpy( buf, "Date: " );                strcat( buf, FormatDateTime( "yyyy-mm-dd hh:nn:ss", Now() ).c_str() );                strcat( buf, "/r/nSubject: " );                strcat( buf, recv_temp->strSubject.c_str() );                strcat( buf, "/r/nFrom: " );                strcat( buf, recv_temp->strFrom.c_str() );                strcat( buf, "/r/nTo: " );                strcat( buf, recv_temp->strTo.c_str() );                strcat( buf, "/r/n" );                if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                {                    nCommandKind = 9;

                        strcpy( buf, "error" );                    break;                }                if( recv_temp->AttachList != NULL && recv_temp->AttachList->Count > 0 )                {                    strcpy( buf, "MIME-Version: 1.0/r/n" );                    strcat( buf, "Content-Type: multipart/mixed;/r/n" );                    strcat( buf, "/tboundary=/"" );                    strcat( buf, strBoundary.c_str() );                    strcat( buf, "/"/r/n/r/n" );//space line                    strcat( buf, "This is a multi-part message in MIME format./r/n/r/n" );//space line                    strcat( buf, ( "--" + strBoundary + "/r/n" ).c_str() );                    strcat( buf, "Content-Type: text/plain;/r/n/tcharset=/"gb2312/"/r/n" );                    strcat( buf, "Content-Transfer-Encoding: 7bit/r/n/r/n" );//space line                    if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                    {                    nCommandKind = 9;

                        strcpy( buf, "error" );                        break;                    }                    if( SendMailText() == -1 )//发送邮件正文失败                    {                    nCommandKind = 9;

                        strcpy( buf, "error" );                        break;                    }                    if( SendAttach() == -1 )//发送邮件附件失败                    {                    nCommandKind = 9;

                        strcpy( buf, "error" );                        break;                    }                    strcpy( buf, ( "/r/n--" + strBoundary + "--/r/n" ).c_str() );                    if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                    {                    nCommandKind = 9;

                        strcpy( buf, "error" );                        break;                    }                }                else                {                    if( SendMailText() == -1 )//发送邮件正文失败                    {                    nCommandKind = 9;

                        strcpy( buf, "error" );                        break;                    }                }                strcpy( buf, "/r/n/r/n/r/n./r/n");                if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                {                    nCommandKind = 9;

                        strcpy( buf, "error" );                    break;                }                nSendFlag = 0;                nCommandKind = 9;            }            else            {                    nCommandKind = 9;

                        strcpy( buf, "error" );            }        break;        case 9 ://应答 quit            if( AnsiString( buf ).AnsiPos( "250" ) != 0 )            {                Fsuccess = 0;                strEndTime = Now().FormatString( "yyyy-mm-dd hh:mm:ss" );                RecvResult();                if( HaveEmail() )                {                    strBeginTime = Now().FormatString( "yyyy-mm-dd hh:mm:ss" );                    strcpy( buf, "mail from: " );                    strcat( buf, FromAddress.c_str() );                    strcat( buf, "/r/n" );                    if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                    {                        closesocket( smtpclient );                        nSendFlag = -1;                        break;                    }                    nSendFlag = 0;                    nCommandKind = 6;                }                else                {                    strcpy( buf, "quit/r/n" );                    if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                    {                        closesocket( smtpclient );                        nSendFlag = -1;                        break;                    }                    nSendFlag = 0;                    nCommandKind = 10;                }            }            else            {                Fsuccess = 1;                RecvResult();                closesocket( smtpclient );                nSendFlag = -1;                Sleep( Ftime );            }        break;        case 10 ://应答            if( AnsiString( buf ).AnsiPos( "221" ) != 0 )            {            Sleep( Ftime );            }            nSendFlag = -1;        break;        }    break;    }}bool __fastcall TSendMailThread::HaveEmail(){         if( RecvEmailList->Count == 0 )        {                  return false;        }        else        {            recv_temp = ( RecvEmailInfo* )RecvEmailList->Items[ 0 ];            RecvEmailList->Delete( 0 );            return true;        }    }    return false;}int __fastcall TSendMailThread::SendMailText(){    int pos, len;    AnsiString strContent;    while( ( pos = recv_temp->strContent.AnsiPos( "/r" ) ) != 0 )    {        len = recv_temp->strContent.Length();        strContent += recv_temp->strContent.SubString( 1, pos );        pos ++;        if( recv_temp->strContent[ pos ] != '/n' )           strContent += "/n";        recv_temp->strContent = recv_temp->strContent.SubString( pos, len - pos + 1 );    }    strContent += recv_temp->strContent + "/r/n";    while( ( pos = strContent.AnsiPos( "/r/n./r/n" ) ) != 0 )    {        strContent = strContent.Insert( ".", pos + 2 );    }    len = 8192;    AnsiString strSend;    while( len <= strContent.Length() )    {        strSend = strContent.SubString( 1, len );        strContent = strContent.SubString( len + 1, strContent.Length() - pos );        if( SOCKET_ERROR == send( smtpclient, strSend.c_str(), strSend.Length(), 0 ) )        {            return -1;        }    }    len = strContent.Length();    if( len > 0 )    {        if( SOCKET_ERROR == send( smtpclient, strContent.c_str(), len, 0 ) )        {            return -1;        }    }    return 0;}int __fastcall TSendMailThread::SendAttach(){    if( recv_temp->AttachList == NULL )        return 0;    TList* List = recv_temp->AttachList;    AttachInfo *pAI;    int         len, last;    char       *chBuf;    for( int i = 0; i < List->Count; i++ )    {        pAI = ( AttachInfo* )List->Items[ i ];        if( pAI != NULL )        {            strcpy( buf, ( "/r/n--" + strBoundary + "/r/n" ).c_str() );            strcat( buf, "Content-Type: application/octet-stream/r/n" );            strcat( buf, "Content-Transfer-Encoding: base64/r/n" );            strcat( buf, "Content-Disposition: attachment; filename=/"" );            if( pAI->FileName == "" )                pAI->FileName = "attach" + AnsiString( i );            strcat( buf, ( pAI->FileName + "/"/r/n/r/n" ).c_str() );            if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )            {                return -1;            }            len = pAI->Length * 4 / 3 + 10;            chBuf = new char[ len ];            Encode_base64( pAI->Content, pAI->Length, chBuf, len );            last = 0;            while( len - last >= 76 )//78bytes per line            {                memcpy( buf, chBuf + last, 76 );                last += 76;                buf[ 76 ] = '/r';                buf[ 77 ] = '/n';                buf[ 78 ] = 0;                if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )                {                    return -1;                }            }            memcpy( buf, chBuf + last, len - last );            buf[ len - last ] = '/r';            buf[ len - last + 1 ] = '/n';            buf[ len - last + 2 ] = 0;            if( SOCKET_ERROR == send( smtpclient, buf, strlen( buf ), 0 ) )            {                return -1;            }            delete [] chBuf;        }    }    return 0;}void __fastcall TSendMailThread::RecvResult(){    int Num = recv_temp->nSendCount - 1;    if( Fsuccess == 0 || Num == 0 )    {        Synchronize( SaveSend );        if( recv_temp->AttachList != NULL )        {            AttachInfo* pAI;            while( recv_temp->AttachList->Count > 0 )            {                pAI = ( AttachInfo* )recv_temp->AttachList->Items[ 0 ];                if( pAI != NULL )                {                    delete [] pAI->Content;                    delete pAI;                }            }            delete recv_temp->AttachList;        }        delete recv_temp;        recv_temp = NULL;        Synchronize( Refresh );    }    else    {        recv_temp->nSendCount = Num;        RecvEmailList->Add( recv_temp );    }}

    头文件:

    #ifndef sendmailH#define sendmailH#include <Classes.hpp>

    struct RecvEmailInfo;struct AttachInfo;

    class TSendMailThread : public TThread{private: int                Ftime;     //休眠时间    int                nRecNum;    TMemoryStream     *SendBuf;    AnsiString         strBeginTime, strEndTime, strBoundary;    AnsiString         strSubject, strFrom, strTo, strContent, strCmdDate, strCmdNum;    RecvEmailInfo     *recv_temp;    BYTE               Fsuccess;//=0成功;=1失败;=2未发    SOCKET             smtpclient;    char               buf[ 8200 ];    int                nCommandKind;    int                nSendFlag;

        TList *RecvEmailList;

        int  __fastcall InitSocket();    void __fastcall SaveSend();    void __fastcall SendDeal();    void __fastcall DealWait();    void __fastcall RecvResult();    void __fastcall Refresh();    bool __fastcall HaveEmail();    int  __fastcall SendMailText();    int  __fastcall SendAttach();protected: void __fastcall Execute();public: __fastcall TSendMailThread(bool CreateSuspended,int sleeptime );};#endif

     


    最新回复(0)