⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smtp.cpp

📁 Visual C++网络通信编程实用案例精逊配套源码 光盘中存放的是书中涉及的所有实例的源代码和经过编译后的应用程序。所有程序均经过测试
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				bSuccess = TRUE;
				pszBody = NULL;
				nBodySize = 0;
			}
		}
		else
			TRACE(_T("No bodypart body text or filename specified!\n"));
	}
	else
	{
		//如果是文本内容
		if (m_bQuotedPrintable)
		{
			//形成发送体
			CString sBody = QuotedPrintableEncode(m_sText);
			nBodySize = _tcslen(sBody);
			pszBody = new char[nBodySize+1];
			strcpy(pszBody, T2A((LPTSTR) (LPCTSTR) sBody));
		}
		else
		{
			nBodySize = _tcslen(m_sText);
			pszBody = new char[nBodySize+1];
			strcpy(pszBody, T2A((LPTSTR) (LPCTSTR) m_sText));
		}
		bSuccess = TRUE;
	}
	return bSuccess;
}

BOOL CSMTPBodyPart::GetFooter(LPSTR& pszFooter, int& nFooterSize)
{
  //For correct operation of the T2A macro, see MFC Tech Note 59
  USES_CONVERSION;

  //Form the MIME footer
	CString sFooter;
  sFooter.Format(_T("\r\n--%s--"), m_sBoundary);
  nFooterSize = _tcslen(sFooter);
  pszFooter = new char[nFooterSize+1];
  strcpy(pszFooter, T2A((LPTSTR) (LPCTSTR) sFooter));

  return TRUE;  
}

int CSMTPBodyPart::GetNumberOfChildBodyParts() const
{
  return m_ChildBodyParts.GetSize();
}

int CSMTPBodyPart::AddChildBodyPart(CSMTPBodyPart& bodyPart)
{
  CSMTPBodyPart* pNewBodyPart = new CSMTPBodyPart(bodyPart);
  pNewBodyPart->m_pParentBodyPart = this;
  ASSERT(m_sContentType.GetLength()); 

  return m_ChildBodyParts.Add(pNewBodyPart);
}

void CSMTPBodyPart::RemoveChildBodyPart(int nIndex)
{
  CSMTPBodyPart* pBodyPart = m_ChildBodyParts.GetAt(nIndex);
  delete pBodyPart;
  m_ChildBodyParts.RemoveAt(nIndex);
}

CSMTPBodyPart* CSMTPBodyPart::GetChildBodyPart(int nIndex)
{
  return m_ChildBodyParts.GetAt(nIndex);
}

CSMTPBodyPart* CSMTPBodyPart::GetParentBodyPart()
{
  return m_pParentBodyPart;
}

void CSMTPBodyPart::FixSingleDot(CString& sBody)
{
  int nFind = sBody.Find(_T("\n."));
  if (nFind != -1)
  {
	  CString sLeft(sBody.Left(nFind+1));
	  CString sRight(sBody.Right(sBody.GetLength()-(nFind+1)));
	  FixSingleDot(sRight);
	  sBody = sLeft + _T(".") + sRight;
  }
}

CSMTPBodyPart* CSMTPBodyPart::FindFirstBodyPart(const CString sContentType)
{
  for (int i=0; i<m_ChildBodyParts.GetSize(); i++)
  {
    CSMTPBodyPart* pBodyPart = m_ChildBodyParts.GetAt(i);
    if (pBodyPart->m_sContentType == sContentType)
      return pBodyPart;
  }
  return NULL;
}



CSMTPMessage::CSMTPMessage() : m_sXMailer(_T("CSMTPConnection v2.17")), m_bMime(FALSE)
{
}

CSMTPMessage::~CSMTPMessage()
{
  //Free up the array memory
  for (int i=0; i<m_ToRecipients.GetSize(); i++)
    delete m_ToRecipients.GetAt(i);
  m_ToRecipients.RemoveAll();

  for (i=0; i<m_CCRecipients.GetSize(); i++)
    delete m_CCRecipients.GetAt(i);
  m_CCRecipients.RemoveAll();

  for (i=0; i<m_BCCRecipients.GetSize(); i++)
    delete m_BCCRecipients.GetAt(i);
  m_BCCRecipients.RemoveAll();
}

void CSMTPMessage::SetCharset(const CString& sCharset)
{
  m_RootPart.SetCharset(sCharset);
}

CString CSMTPMessage::GetCharset() const
{
  return m_RootPart.GetCharset();
}

int CSMTPMessage::GetNumberOfRecipients(RECIPIENT_TYPE RecipientType) const
{
  int nSize = 0;
  switch (RecipientType)
  {
    case TO:  nSize = m_ToRecipients.GetSize();  break;
    case CC:  nSize = m_CCRecipients.GetSize();  break;
    case BCC: nSize = m_BCCRecipients.GetSize(); break;
    default: ASSERT(FALSE);                      break;
  }

	return nSize;
}

int CSMTPMessage::AddRecipient(CSMTPAddress& recipient, RECIPIENT_TYPE RecipientType)
{
  int nIndex = -1;

  CSMTPAddress* pNewRecipient = new CSMTPAddress(recipient);

  switch (RecipientType)
  {
    case TO:  nIndex = m_ToRecipients.Add(pNewRecipient);  break;
    case CC:  nIndex = m_CCRecipients.Add(pNewRecipient);  break;
    case BCC: nIndex = m_BCCRecipients.Add(pNewRecipient); break;
    default: ASSERT(FALSE);                            break;
  }

  return nIndex;
}

void CSMTPMessage::RemoveRecipient(int nIndex, RECIPIENT_TYPE RecipientType)
{
  switch (RecipientType)
  {
    case TO:  
    {
      delete m_ToRecipients.GetAt(nIndex);
      m_ToRecipients.RemoveAt(nIndex);  
      break;
    }
    case CC:  
    {
      delete m_CCRecipients.GetAt(nIndex);
      m_CCRecipients.RemoveAt(nIndex);  
      break;
    }
    case BCC: 
    {
      delete m_BCCRecipients.GetAt(nIndex);
      m_BCCRecipients.RemoveAt(nIndex); 
      break;
    }
    default:  
    {
      ASSERT(FALSE);                    
      break;
    }
  }
}

CSMTPAddress* CSMTPMessage::GetRecipient(int nIndex, RECIPIENT_TYPE RecipientType)
{
  switch (RecipientType)
  {
    case TO:  return m_ToRecipients.GetAt(nIndex);   break;
    case CC:  return m_CCRecipients.GetAt(nIndex);   break;
    case BCC: return m_BCCRecipients.GetAt(nIndex);  break;
    default: ASSERT(FALSE); return (CSMTPAddress*) NULL; break;
  }
}

int CSMTPMessage::AddBodyPart(CSMTPBodyPart& Attachment)
{
	SetMime(TRUE); //Body parts implies Mime
	return m_RootPart.AddChildBodyPart(Attachment);
}

void CSMTPMessage::RemoveBodyPart(int nIndex)
{
	m_RootPart.RemoveChildBodyPart(nIndex);
}

CSMTPBodyPart* CSMTPMessage::GetBodyPart(int nIndex)
{
	return m_RootPart.GetChildBodyPart(nIndex);
}

int CSMTPMessage::GetNumberOfBodyParts() const
{
	return m_RootPart.GetNumberOfChildBodyParts();
}

void CSMTPMessage::AddCustomHeader(const CString& sHeader)
{
  m_CustomHeaders.Add(sHeader);
}

CString CSMTPMessage::GetCustomHeader(int nIndex)
{
  return m_CustomHeaders.GetAt(nIndex);
}

int CSMTPMessage::GetNumberOfCustomHeaders() const
{
  return m_CustomHeaders.GetSize();
}

void CSMTPMessage::RemoveCustomHeader(int nIndex)
{
  m_CustomHeaders.RemoveAt(nIndex);
}

CString CSMTPMessage::GetHeader()
{
  //Hive away the locale so that we can restore it later. We
  //require the English locale to ensure the date header is
  //formed correctly
  CString sOldLocale = _tsetlocale(LC_TIME, NULL);    
  _tsetlocale(LC_TIME, _T("english"));

  //Form the Timezone info which will form part of the Date header
  TIME_ZONE_INFORMATION tzi;
  int nTZBias;
  if (GetTimeZoneInformation(&tzi) == TIME_ZONE_ID_DAYLIGHT)
    nTZBias = tzi.Bias + tzi.DaylightBias;
  else
    nTZBias = tzi.Bias;
  CString sTZBias;
  sTZBias.Format(_T("%+.2d%.2d"), -nTZBias/60, nTZBias%60);

  //Create the "Date:" part of the header
  CTime now(CTime::GetCurrentTime());
  CString sDate(now.Format(_T("%a, %d %b %Y %H:%M:%S ")));
  sDate += sTZBias;

  //Create the "To:" part of the header
  CString sTo;
  for (int i=0; i<GetNumberOfRecipients(TO); i++)
  {
    CSMTPAddress* pRecipient = GetRecipient(i, TO);
    if (i)
 		  sTo += _T(",");
    ASSERT(pRecipient);
    sTo += pRecipient->GetRegularFormat();
  }

  //Create the "Cc:" part of the header
  CString sCc;
  for (i=0; i<GetNumberOfRecipients(CC); i++)
  {
    CSMTPAddress* pRecipient = GetRecipient(i, CC);
    if (i)
 		  sCc += _T(",");
    ASSERT(pRecipient);
    sCc += pRecipient->GetRegularFormat();
  }

  //No Bcc info added in header

  //Add the From and to fields
  CString sReply;
  sReply.Format(_T("From: %s\r\nTo: %s\r\n"),  HeaderEncode(m_From.GetRegularFormat()), HeaderEncode(sTo));
  CString sBuf(sReply);
  
  //Add the CC field if there is any
  if (sCc.GetLength())
  {
    sReply.Format(_T("Cc: %s\r\n"), HeaderEncode(sCc));
    sBuf += sReply;
  }

  //Add the subject, Date and X-Mailer fields
  sReply.Format(_T("Subject: %s\r\nDate: %s\r\nX-Mailer: %s\r\n"), HeaderEncode(m_sSubject), HeaderEncode(sDate), HeaderEncode(m_sXMailer));
  sBuf += sReply;

  //Add the Mime header if needed
  BOOL bHasChildParts = (m_RootPart.GetNumberOfChildBodyParts() != 0);
  if (bHasChildParts && m_bMime)
  {
    sReply.Format(_T("MIME-Version: 1.0\r\nContent-Type: %s; boundary=\"%s\"\r\n"), m_RootPart.GetContentType(), m_RootPart.GetBoundary());
    sBuf += sReply;
  }
  else if (!bHasChildParts && m_bMime)
  {
    sReply.Format(_T("MIME-Version: 1.0\r\nContent-Type: %s\r\n"), m_RootPart.GetContentType());
    sBuf += sReply;
  }
  sBuf += _T("Content-Transfer-Encoding: quoted-printable\r\n");


	//Add the optional Reply-To Field
	if (m_ReplyTo.m_sEmailAddress.GetLength())
	{
		CString sReply;
		sReply.Format(_T("Reply-To: %s\r\n"), m_ReplyTo.GetRegularFormat());
		sBuf += sReply;
	}

  //Add the custom headers
  int nCustomHeaders = m_CustomHeaders.GetSize();
  for (i=0; i<nCustomHeaders; i++)
  {
    CString sHeader = m_CustomHeaders.GetAt(i);
    sBuf += sHeader;
    
    //Add line separators for each header bar the final one
    if (i < (nCustomHeaders-1))
      sBuf += _T("\r\n");
  }

  //Add the line separator between the header and what will follow
  //i.e. the body
	sBuf += _T("\r\n");

  // restore original locale
  _tsetlocale(LC_TIME, sOldLocale);

	//Return the result
	return sBuf;
}

//Converts header text to its encoded form according to RFC 2047
CString CSMTPMessage::HeaderEncode(const CString& sText) const
{
  int nSize = sText.GetLength();

  //Determine if a translation is needed
  BOOL bTranslationNeeded = FALSE;
  for (int i=0; i<nSize && !bTranslationNeeded; i++)
  {
    BYTE c = (BYTE) sText[i];
    bTranslationNeeded = (c > 127);
  }

  CString sOut;
  if (bTranslationNeeded)
  {
    sOut.Format(_T("=?%s?q?"), m_RootPart.GetCharset());
    for (i=0; i<nSize; i++)
    {
      BYTE c = (BYTE) sText[i];
      if (c == ' ') // A space
        sOut += _T('_');
      else if ((c > 127) || (c == '=') || (c == '?') || (c == '_'))
      {
        //Must Quote the text
        sOut += _T('=');
        sOut += CSMTPBodyPart::HexDigit((c & 0xF0) >> 4);
        sOut += CSMTPBodyPart::HexDigit(c & 0x0F);
      }
      else
        sOut += TCHAR(c);
    }
    sOut += _T("?=");
  }
  else
  {
    //Just pass the text thro unmodified
    sOut = sText;
  }

  return sOut;
}

CSMTPAddressArray* CSMTPMessage::ParseMultipleRecipients(const CString& sRecipients)
{
	ASSERT(sRecipients.GetLength()); //An empty string is now allowed

  //What will be the return value
  CSMTPAddressArray* pRecipients = new CSMTPAddressArray;
	
	//Loop through the whole string, adding recipients as they are encountered
	int length = sRecipients.GetLength();
	TCHAR* buf = new TCHAR[length + 1];	// Allocate a work area (don't touch parameter itself)
	_tcscpy(buf, sRecipients);
	for (int pos=0, start=0; pos<=length; pos++)
	{
		//Valid separators between addresses are ',' or ';'
		if ((buf[pos] == _T(',')) || (buf[pos] == _T(';')) || (buf[pos] == 0))
		{
			buf[pos] = 0;	//Redundant when at the end of string, but who cares.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -