email 邮件发送源代码(c++实现)

//ZBase64为base64编码的实现类,参考我前面的文章 

bool CreateSocket() {
 if(WSAStartup(MAKEWORD(2,2),&wsadata_) == SOCKET_ERROR)
 {
        errornum_=WSA_STARTUP_ERROR;
  ReleaseSocket();
  return false;
 }
 
 if((socket_ = socket(AF_INET,SOCK_STREAM,0)) == SOCKET_ERROR)
 {
        errornum_=WSA_SOCKET_ERROR;
        ReleaseSocket();
        return false;
    }

    int time = 5000;
    if(setsockopt(socket_,SOL_SOCKET,SO_RCVTIMEO,(char *)&time,sizeof(time)) == SOCKET_ERROR)
    {
        errornum_=WSA_SETSOCKAPT_ERROR;
        ReleaseSocket();
        return false;
    }
    if(setsockopt(socket_,SOL_SOCKET,SO_SNDTIMEO,(char *)&time,sizeof(time)) == SOCKET_ERROR)
    {
        errornum_=WSA_SETSOCKAPT_ERROR;
        ReleaseSocket();
        return false;
    }

    errornum_=ZSMTP_NO_ERROR;
    return true;
}

bool CheckResponse(const char* RecvCode) {
  char Buf[1024]={0};
  if(recv(socket_,Buf,1024,0) == SOCKET_ERROR)
        {
            errornum_=WSA_RECV_ERROR;
            return false;
        }
  return RecvCode[0] == Buf[0] && \
      RecvCode[1] == Buf[1] && \
      RecvCode[2] == Buf[2] ? true : false; 
 
}

/**    @fn Connect
 *    @brief connect to smtp server
 *    @param
 *    @return true if success
 */
bool Connect() {
    if (smtpaddr_.empty())
    {
        errornum_=UNDEF_SERVERADDR;
        return false;
    }
    if (port_==0)
    {
        errornum_=UNDEF_SERVERPORT;
        return false;
    }
 if(!CreateSocket())
  return false;

 if((hostent_=gethostbyname(smtpaddr_.c_str()))==NULL)
 {
        errornum_=WSA_GETHOSTBYNAME_ERROR;
  ReleaseSocket();
  return false; 
 }

 if(hostent_->h_addr_list[0] == NULL)
 {
        errornum_=WSA_GETHOSTBYNAME_ERROR;
  ReleaseSocket();
  return false;
 }

 memset(&sockaddr_in_,0,sizeof(sockaddr_in_));
 sockaddr_in_.sin_family = AF_INET;
 sockaddr_in_.sin_port   = htons(port_);
 sockaddr_in_.sin_addr.S_un.S_addr = *(ULONG *)hostent_->h_addr_list[0];

 //连接服务器
 if(connect(socket_,(sockaddr *)&sockaddr_in_,sizeof(sockaddr_in_)) == SOCKET_ERROR)
 {
        errornum_=WSA_CONNECT_ERROR;
  ReleaseSocket();
  return false;
 }
 if(!CheckResponse("220")) return false;

 //向服务器发送"HELO "+服务器名
 string strTmp="HELO "+smtpaddr_+"\r\n";
 if(send(socket_,strTmp.c_str(),strTmp.length(),0) == SOCKET_ERROR) 
 {
        errornum_=COMMAND_HELO;
  ReleaseSocket();
  return false;
 }
 if(!CheckResponse("250"))
    {
        errornum_=SERVER_NOT_READY;
        return false;
    }

 return true;
}

/**    @fn Validate
 *    @brief validate username_ and password_
 *    @param
 *    @return true if username_ and password_ are correct
 */
bool Validate() {
    if (username_.empty())
    {
        errornum_=UNDEF_USER_NAME;
        return false;
    }
    if (password_.empty())
    {
        errornum_=UNDEF_PASSWORD;
        return false;
    }
 ZBase64 base64;

 //发送"AUTH LOGIN"
 if(send(socket_,"AUTH LOGIN\r\n",strlen("AUTH LOGIN\r\n"),0) == SOCKET_ERROR)
 {
        errornum_=COMMAND_AUTH_LOGIN;
  ReleaseSocket();
  return false;
 }
 if(!CheckResponse("334"))
    {
        errornum_=COMMAND_AUTH_LOGIN;
        return false;
    }

 //发送经base64编码的用户名
 string strUserName=base64.Encode((unsigned char *)username_.c_str(),username_.length())+"\r\n";
 if(send(socket_,strUserName.c_str(),strUserName.length(),0) == SOCKET_ERROR)
 {
        errornum_=WSA_SEND_ERROR;
  ReleaseSocket();
  return false;
 }
 if(!CheckResponse("334")) return false;

 //发送经base64编码的密码
 string strPassword=base64.Encode((unsigned char *)password_.c_str(),password_.length())+"\r\n";
 if(send(socket_,strPassword.c_str(),strPassword.length(),0) == SOCKET_ERROR)
 {
        errornum_=WSA_SEND_ERROR;
  ReleaseSocket();
  return false;
 }
 if(!CheckResponse("235"))
    {
        errornum_=BAD_LOGIN_PASS;
        return false;
    }

 return true;
}

/**    @fn Send
 *    @brief send an email
 *    @param
 *    @return true if success
 */
bool Send() {
    if (!Connect())
    {
        return false;
    }
    if (!Validate())
    {
        return false;
    }
 if(sendfrom_.empty())
    {
        errornum_=UNDEF_SEND_FROM;
        return false;
    }
 if(recipient_.size()<=0)
    {
        errornum_=UNDEF_RECIPIENTS;
        return false;
    }

    if (sendername_.empty())
    {
        errornum_=UNDEF_SENDER_NAME;
        return false;
    }
    if (receivername_.empty())
    {
        errornum_=UNDEF_RECEVER_NAME;
        return false;
    }
    if (subject_.empty())
    {
        errornum_=UNDEF_SUBJECT;
        return false;
    }

 string strTmp;
 ZBase64 base64;

 //发送MAIL FROM:<abc@xyz.com>
 strTmp="MAIL FROM:<"+sendfrom_+">\r\n";
 if(send(socket_,strTmp.c_str(),strTmp.length(),0) == SOCKET_ERROR)
 {
        errornum_=WSA_SEND_ERROR;
  ReleaseSocket();
  return false;
 }
 if(!CheckResponse("250"))
    {
        errornum_=COMMAND_MAIL_FROM;
        return false;
    }

 //发送RCPT To:<abc@xyz.com>
 for(unsigned int i=0;i<recipient_.size();++i)
 {
  strTmp="RCPT To:<"+recipient_[i]+">\r\n";
  if(send(socket_,strTmp.c_str(),strTmp.length(),0) == SOCKET_ERROR)
  {
            errornum_=WSA_SEND_ERROR;
   ReleaseSocket();
   return false;
  }
  if(!CheckResponse("250"))
        {
            errornum_=COMMAND_RCPT_TO;
            return false;
        }
 }

 //发送"DATA\r\n"
 if(send(socket_,"DATA\r\n",strlen("DATA\r\n"),0) == SOCKET_ERROR)
 {
        errornum_=WSA_SEND_ERROR;
  ReleaseSocket();
  return false;
 }
 if(!CheckResponse("354"))
    {
        errornum_=COMMAND_DATA;
        return false;
    }

 //"Mail From:sendername_<xxx@mail.com>\r\n"
 strTmp="From:"+sendername_+"<"+sendfrom_+">\r\n";

 //"subject_: 邮件主题\r\n"
 strTmp+="Subject:"+subject_+"\r\n";

 //"MIME_Version:1.0\r\n"
 strTmp+="MIME_Version:1.0\r\n";

 //"X-Mailer:Smtp Client By xxx"//版权信息
 strTmp+="X-Mailer:"; strTmp+=COPYRIGHT; strTmp+="\r\n";

 //"MIME_Version:1.0\r\n"
 strTmp+="MIME_Version:1.0\r\n";

 //"content_-type:multipart/mixed;Boundary=xxx\r\n\r\n";
 strTmp+="Content-type:multipart/mixed;Boundary=";
 strTmp+=BOUNDARY;
 strTmp+="\r\n\r\n";

 //先将HEADER部分发送过去
 if(send(socket_,strTmp.c_str(),strTmp.length(),0) == SOCKET_ERROR)
 {
        errornum_=WSA_SEND_ERROR;
  ReleaseSocket();
  return false; 
 }

 //邮件主体
 strTmp="--";
 strTmp+=BOUNDARY;
 strTmp+="\r\n";
 strTmp+=ishtml_ ? "Content-type:text/html;Charset=gb2312\r\n" : "Content-type:text/plain;Charset=gb2312\r\n";
 strTmp+="Content-Transfer-Encoding:8bit\r\n\r\n";

 //邮件内容
 strTmp+=content_+"\r\n\r\n";

 //将邮件内容发送出去
 if(send(socket_,strTmp.c_str(),strTmp.length(),0) == SOCKET_ERROR)
 {
        errornum_=WSA_SEND_ERROR;
  ReleaseSocket();
  return false; 
 }

 /*
 附件处理
 对文件内容分段进行base64编码,编码一小段,传送一小段
 */

 for(unsigned int i=0;i<files_.size();++i)
 {
  strTmp="--";
  strTmp+=BOUNDARY;
  strTmp+="\r\n";

  strTmp+="Content-Type:application/octet-stream;Name=";
  strTmp+=files_[i].substr(files_[i].find_last_of("\\")+1).c_str();
  strTmp+="\r\n";
  strTmp+="Content-Disposition:attachment;FileName=";
  strTmp+=files_[i].substr(files_[i].find_last_of("\\")+1).c_str();
  strTmp+="\r\n";
  strTmp+="Content-Transfer-Encoding:Base64\r\n\r\n";

  if(send(socket_,strTmp.c_str(),strTmp.length(),0) == SOCKET_ERROR)
  {
            errornum_=WSA_SEND_ERROR;
   ReleaseSocket();
   return false; 
  }
  errno_t err;
  FILE* fin;
  err=fopen_s(&fin,files_[i].c_str(),"rb");
        if (err!=0)
        {
            errornum_=OPEN_FILE_ERROR;
        }
        char* Buf=new(std::nothrow) char[BUFFER_READ+1];
        if (Buf==NULL)
        {
            errornum_=LACK_OF_MEMORY;
            return false;
        }
  memset(Buf,0,BUFFER_READ+1);
  size_t ReadSize=fread(Buf,sizeof(char),BUFFER_READ,fin);
  while((ReadSize>0))
  {
         
   strTmp=base64.Encode((unsigned char*)Buf,ReadSize);
   if(send(socket_,strTmp.c_str(),strTmp.length(),0) == SOCKET_ERROR)
   {
                errornum_=WSA_SEND_ERROR;
    ReleaseSocket();
    return false; 
   }
   memset(Buf,0,BUFFER_READ+1);
   ReadSize=fread(Buf,1,BUFFER_READ,fin);
  }
  delete[] Buf;
  fclose(fin);
 } // end for

 //界尾
 strTmp="--";
 strTmp+=BOUNDARY;
 strTmp+="--\r\n.\r\n";

 if(send(socket_,strTmp.c_str(),strTmp.length(),0) == SOCKET_ERROR)
 {
        errornum_=WSA_SEND_ERROR;
  ReleaseSocket();
  return false;
 }
 if(!CheckResponse("250"))
    {
        errornum_=SERVER_NOT_READY;
        return false;
    }

 //退出
 if(send(socket_,"QUIT\r\n",strlen("QUIT\r\n"),0) == SOCKET_ERROR)
 {
        errornum_=WSA_SEND_ERROR;
  ReleaseSocket();
  return false;
 }
 if(!CheckResponse("221"))
    {
        errornum_=COMMAND_QUIT;
        return false;
    }
 ReleaseSocket();
 return true;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值