使用smtp发送邮件(源码)

 

源文件:

#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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
使用Python发送邮件可以通过smtplib和email两个模块来实现。首先,需要导入相应的模块。然后,创建一个SMTP对象,指定邮件服务器的地址和端口号。接下来,使用SMTP对象的login方法登录到邮件服务器,需要提供发件人的邮箱地址和授权码。然后,创建一个MIMEMultipart对象作为邮件的主体,设置发件人、收件人和主题。可以使用MIMEText对象来设置邮件的正文内容。如果需要发送HTML格式的邮件,可以使用MIMEText对象的第二个参数设置为'html'。如果需要发送带附件的邮件,可以使用MIMEMultipart对象的attach方法添加附件。最后,使用SMTP对象的sendmail方法发送邮件,需要提供发件人、收件人和邮件内容。以下是一个使用SMTP发送邮件的简单示例代码: ```python import smtplib from email.header import Header from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText # 创建邮件主体对象 email = MIMEMultipart() # 设置发件人、收件人和主题 email\['From'\] = 'xxxxxxxxx@qq.com' email\['To'\] = '78901@qq.com;12345@163.com' email\['Subject'\] = Header('上半年工作情况汇报', 'utf-8') # 添加邮件正文内容 content = """好好学习,天天向上""" # 默认为“plain” email.attach(MIMEText(content, 'plain', 'utf-8')) # 创建SMTP_SSL对象(连接邮件服务器) smtp_obj = smtplib.SMTP_SSL('smtp.qq.com', 465) # 通过用户名和授权码进行登录 smtp_obj.login('xxxxxxxxx@qq.com', '邮件服务器的授权码') # 发送邮件(发件人、收件人、邮件内容(字符串)) smtp_obj.sendmail( 'xxxxxxxxx@qq.com', \['78901@qq.com', '12345@163.com'\], email.as_string() ) ``` 如果需要发送带附件的邮件,可以使用MIMEMultipart对象的attach方法添加附件。以下是一个带附件的邮件发送示例代码: ```python import smtplib from email.header import Header from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication # 创建邮件主体对象 email = MIMEMultipart() # 设置发件人、收件人和主题 email\['From'\] = 'xxxxxxxxx@qq.com' email\['To'\] = '78901@qq.com;12345@163.com' email\['Subject'\] = Header('带附件的邮件', 'utf-8') # 添加邮件正文内容 content = """这是一封带附件的邮件""" email.attach(MIMEText(content, 'plain', 'utf-8')) # 添加附件 attachment = MIMEApplication(open('附件文件路径', 'rb').read()) attachment.add_header('Content-Disposition', 'attachment', filename='附件文件名') email.attach(attachment) # 创建SMTP_SSL对象(连接邮件服务器) smtp_obj = smtplib.SMTP_SSL('smtp.qq.com', 465) # 通过用户名和授权码进行登录 smtp_obj.login('xxxxxxxxx@qq.com', '邮件服务器的授权码') # 发送邮件(发件人、收件人、邮件内容(字符串)) smtp_obj.sendmail( 'xxxxxxxxx@qq.com', \['78901@qq.com', '12345@163.com'\], email.as_string() ) ``` 请注意,需要将代码中的发件人邮箱地址、收件人邮箱地址、邮件服务器地址、端口号、授权码以及附件文件路径和附件文件名替换为实际的值。 #### 引用[.reference_title] - *1* [Python -- 使用SMTP发送邮件](https://blog.csdn.net/wudj810818/article/details/50418021)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Python——SMTP发送邮件](https://blog.csdn.net/ljj950408/article/details/81583187)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [利用SMTP服务器发送邮件(python)](https://blog.csdn.net/m0_53080574/article/details/127018381)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yueyue

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值