VC++利用SMTP协议发送电子邮件

时间:2021-02-10 18:11:58

bool mailSend(string to, string title, string body)
{
 SOCKET sockSmtp = 0;
 sockaddr_in addrSmtp;

 const char *smtpServer = "mail.game247.net";
 const char *smtpUser = "username";
 const char *smtpPass = "userpassword";
 const char *senderMail = "username@game247.net";

 if(sockSmtp != NULL)
 {
  closesocket(sockSmtp);
  sockSmtp = NULL;
 }

 if(sockSmtp == NULL)
 {
  sockSmtp = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 }

 struct in_addr in;
 hostent *hosts = gethostbyname(smtpServer);
 memcpy((char**)&(in),hosts->h_addr,hosts->h_length);
 
 string addrc = inet_ntoa(in);

 addrSmtp.sin_family = AF_INET;
 addrSmtp.sin_addr.s_addr = in.S_un.S_addr;
 addrSmtp.sin_port = htons(25);

 int ret = 0;
 ret = connect(sockSmtp, (LPSOCKADDR)&addrSmtp, sizeof(addrSmtp));
 if(ret == SOCKET_ERROR)
 {
  char *err = new char[1024];
  sprintf(err,"连接失败%d",GetLastError());
  printf("%s/n",err);
  return false;
 }

 const char *s = new char[MAX_PACKET_SIZE];
 const char *r = new char[MAX_PACKET_SIZE];

 memset((void*)s,0,MAX_PACKET_SIZE);
 memset((void*)r,0,MAX_PACKET_SIZE);
 int len;
 string response;

 //等待服务器回应
 len = recv(sockSmtp,(char*)r,MAX_PACKET_SIZE,0);

 if(len)
 {
  response = r;
  int position = response.substr(0,3).compare("220");
  if(position == 0)
  {
   len = sprintf((char*)s,"AUTH LOGIN/r/n");
   len = send(sockSmtp,s,strlen(s),0);
  }
  else
  {
   printf(r);
   if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
   return false;
  }
 }
 else
 {
  if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
  return false;
 }

 //等待登录回应
 len = recv(sockSmtp,(char*)r,MAX_PACKET_SIZE,0);
 if(len)
 {
  response = r;
  int position = response.substr(0,3).compare("334");
  if(position == 0)
  {
   unsigned char src[MAX_PACKET_SIZE];
   unsigned char *dst = (unsigned char*)smtpUser;
   len = strlen((char*)dst);
   int len2 = sizeof(src);

   base64_encode(src,&len2,dst,len);
   len = sprintf((char*)s,"%s/r/n",(const char*)src);
   len = send(sockSmtp,s,strlen(s),0);
  }
  else
  {
   if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
   printf(r);
   return false;
  }
 }
 else
 {
  if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
  return false;
 }

 //发送完用户名后等待回应
 len = recv(sockSmtp,(char*)r,MAX_PACKET_SIZE,0);
 if(len)
 {
  response = r;
  int position = response.substr(0,3).compare("334");
  if(position == 0)
  {
   unsigned char src[MAX_PACKET_SIZE];
   unsigned char *dst = (unsigned char*)smtpPass;
   len = strlen((char*)dst);
   int len2 = sizeof(src);

   base64_encode(src,&len2,dst,len);
   len = sprintf((char*)s,"%s/r/n",(const char*)src);
   len = send(sockSmtp,s,strlen(s),0);
  }
  else
  {
   if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
   printf(r);
   return false;
  }
 }
 else
 {
  if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
  return false;
 }

 //发送完密码后等待回应,登录成功后即say hello
 len = recv(sockSmtp,(char*)r,MAX_PACKET_SIZE,0);
 if(len)
 {
  response = r;
  int position = response.substr(0,3).compare("235");
  if(position == 0)
  {
   const char *local_name = new char[MAX_PACKET_SIZE];
   if(gethostname((char *)local_name, MAX_PACKET_SIZE) != 0 )
   {
    if(sockSmtp)
     closesocket(sockSmtp);
    sockSmtp = NULL;
    return false;
   }

   len = sprintf((char*)s,"HELO %s/r/n",local_name);
   len = send(sockSmtp,s,strlen(s),0);   
  }
  else
  {
   if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
   printf(r);
   return false;
  }
 }
 else
 {
  if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
  return false;
 }

 //say hello后等待服务器回应,准备发送header部份
 len = recv(sockSmtp,(char*)r,MAX_PACKET_SIZE,0);
 if(len)
 {
  response = r;
  int position = response.substr(0,3).compare("250");
  if(position == 0)
  {
   len = sprintf((char*)s,"MAIL FROM: %s/r/n",senderMail);
   len = send(sockSmtp,s,strlen(s),0);   
  }
  else
  {
   if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
   printf(r);
   return false;
  }
 }
 else
 {
  if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
  return false;
 }

 //header部份
 len = recv(sockSmtp,(char*)r,MAX_PACKET_SIZE,0);
 if(len)
 {
  response = r;
  int position = response.substr(0,3).compare("250");
  if(position == 0)
  {
   len = sprintf((char*)s,"RCPT TO: %s/r/n",to.c_str());
   len = send(sockSmtp,s,strlen(s),0);   
  }
  else
  {
   if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
   printf(r);
   return false;
  }
 }
 else
 {
  if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
  return false;
 }

 //header部份
 len = recv(sockSmtp,(char*)r,MAX_PACKET_SIZE,0);
 if(len)
 {
  response = r;
  int position = response.substr(0,3).compare("250");
  if(position == 0)
  {
   len = sprintf((char*)s,"DATA/r/n");
   len = send(sockSmtp,s,strlen(s),0);   
  }
  else
  {
   if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
   printf(r);
   return false;
  }
 }
 else
 {
  if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
  return false;
 }

 //header部份
 len = recv(sockSmtp,(char*)r,MAX_PACKET_SIZE,0);
 if(len)
 {
  response = r;
  int position = response.substr(0,3).compare("354");
  if(position == 0)
  {
   char date_string[MAX_PACKET_SIZE];
   time_t seconds;
   time(&seconds);
   strftime(date_string, MAX_PACKET_SIZE,
      "%a, %d %b %y %H:%M:%S +0800",
      localtime(&seconds));          // +0800 maybe hard code
   sprintf((char*)s,"From: %s/r/nTo: %s/r/nDate: %s/r/nSubject: %s/r/nX-Mailer: %s/r/nX-Priority: %s/r/nMIME-Version: 1.0/r/nContent-type: multipart/mixed; boundary=/"%s/"/r/n/r/n",
    senderMail,to.c_str(),date_string,title.c_str(),"SMailer","3","#BOUNDARY#"); 
   len = send(sockSmtp,s,strlen(s),0); 
  }
  else
  {
   if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
   printf(r);
   return false;
  }
 }
 else
 {
  if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
  return false;
 }

 //邮件正文
 sprintf((char*)s,"--%s/r/nContent-Type: %s/r/nContent-Disposition: %s/r/nContent-Transfer-Encoding: %s/r/n/r/n%s/r/n/r/n","#BOUNDARY#","text/plain; charset=gb2312","","8bit",body.c_str());
 len = send(sockSmtp,s,strlen(s),0); 

 //邮件结束
 sprintf((char*)s,"/r/n--%s--/r/n./r/n","#BOUNDARY#");
 len = send(sockSmtp,s,strlen(s),0); 

 len = recv(sockSmtp,(char*)r,MAX_PACKET_SIZE,0);
 if(len)
 {
  response = r;
  int position = response.substr(0,3).compare("250");
  if(position == 0)
  {
   //退出连接
   sprintf((char*)s,"QUIT/r/n");
   len = send(sockSmtp,s,strlen(s),0); 
  }
  else
  {
   if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
   printf(r);
   return false;
  }
 }
 else
 {
  if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
  return false;
 }

 //断开连接
 len = recv(sockSmtp,(char*)r,MAX_PACKET_SIZE,0);
 if(len)
 {
  response = r;
  int position = response.substr(0,3).compare("221");
  if(position == 0)
  {
   if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
  }
  else
  {
   if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
   printf(r);
   return false;
  }
 }
 else
 {
  if(sockSmtp)
    closesocket(sockSmtp);
   sockSmtp = NULL;
  return false;
 }

 return true;

}