ITdaan
首页
最新
原创
最火
关于
搜索答案
中文简体
相关内容
C++發送郵件和附件
本文转载自
lvdongjie
查看原文
2014-12-06
79
c++
/
邮件
c++
socket
null
delete
服務器
stream
頭文件
[cpp]
view plain
copy
/***********************************************************************
*發送郵件模塊頭文件
*可以發送文本和附件(支持多個附件一起發送)
*************************************************************************/
#pragma once
struct sMailInfo
//郵件信息
{
char* m_pcUserName;
//用戶登錄郵箱的名稱
char* m_pcUserPassWord;
//用戶登錄郵箱的密碼
char* m_pcSenderName;
//用戶發送時顯示的名稱
char* m_pcSender;
//發送者的郵箱地址
char* m_pcReceiver;
//接收者的郵箱地址
char* m_pcTitle;
//郵箱標題
char* m_pcBody;
//郵件文本正文
char* m_pcIPAddr;
//服務器的IP
char* m_pcIPName;
//服務器的名稱(IP與名稱二選一,優先取名稱)
sMailInfo(){memset(
this,0,
sizeof(sMailInfo));}
};
class CSendMail
{
public:
CSendMail(
void);
~CSendMail(
void);
public:
bool SendMail(sMailInfo &smailInfo);
//發送郵件,需要在發送的時候初始化郵件信息
void AddFilePath(
char * pcFilePath);
//添加附件的決定路徑到附件列表中
void DeleteFilePath(
char* pcFilePath);
//刪除附件路徑,如果有的話
void DeleteAllPath(
void);
//刪除全部附件的路徑
protected:
void GetFileName(
char* fileName,
char* filePath);
//從附件的路徑中獲取文件名稱
void Char2Base64(
char* pBuff64,
char* pSrcBuff,
int iLen);
//把char類型轉換成Base64類型
bool CReateSocket(SOCKET &sock);
//建立socket連接
bool Logon(SOCKET &sock);
//登錄郵箱,主要進行發郵件前的准備工作
int GetFileData(
char* FilePath);
//由文件路徑獲取附件內容
bool SendHead(SOCKET &sock);
//發送郵件頭
bool SendTextBody(SOCKET &sock);
//發送郵件文本正文
bool SendFileBody(SOCKET &sock);
//發送郵件附件
bool SendEnd(SOCKET &sock);
//發送郵件結尾
protected:
CList<
char*,
char*> m_pcFilePathList;
//記錄附件路徑
char m_cSendBuff[4096];
//發送緩沖區
char m_cReceiveBuff[1024];
char* m_pcFileBuff;
//指向附件內容
sMailInfo m_sMailInfo;
};
模塊實現文件
[cpp]
view plain
copy
/************************************************************************
* 發送郵件模塊
*可以發送文本和附件(支持多個附件一起發送)
*Date:2011-12-01
************************************************************************/
#include "StdAfx.h"
#include "SendMail.h"
#include "winsock2.h"
#pragma comment(lib,"WSOCK32")
CSendMail::CSendMail(
void)
{
m_pcFileBuff=NULL;
memset(m_cSendBuff,0,
sizeof(m_cSendBuff));
memset(m_cReceiveBuff,0,
sizeof(m_cReceiveBuff));
}
CSendMail::~CSendMail(
void)
{
DeleteAllPath();
}
void CSendMail::Char2Base64(
char* pBuff64,
char* pSrcBuff,
int iLen)
{
//1 1 1 1 1 1 1 1
// 分配給pBuff64 ↑ 分配給pBuff64+1
// point所在的位置
static
char Base64Encode[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//base64所映射的字符表
int point;
//每一個源字符拆分的位置,可取2,4,6;初始為2
point=2;
int i;
int iIndex;
//base64字符的索引
char n=0;
//上一個源字符的殘留值
for(i=0;i<iLen;i++)
{
if(point==2)
{
iIndex=((*pSrcBuff)>>point)&0x3f;
//取得pSrcBuff的高point位
}
else
if (point==4)
{
iIndex=((*pSrcBuff)>>point)&0xf;
//取得pSrcBuff的高point位
}
else
if(point==6)
{
iIndex=((*pSrcBuff)>>point)&0x3;
//取得pSrcBuff的高point位
}
iIndex+=n;
//與pSrcBuff-1的低point結合組成Base64的索引
*pBuff64++=Base64Encode[iIndex];
//由索引表得到pBuff64
n=((*pSrcBuff)<<(6-point));
//計算源字符中的殘留值
n=n&0x3f;
//確保n的最高兩位為0
point+=2;
//源字符的拆分位置上升2
if(point==8)
//如果拆分位置為8說明pSrcBuff有6位殘留,可以組成一個完整的Base64字符,所以直接再組合一次
{
iIndex=(*pSrcBuff)&0x3f;
//提取低6位,這就是索引了
*pBuff64++=Base64Encode[iIndex];
//
n=0;
//殘留值為0
point=2;
//拆分位置設為2
}
pSrcBuff++;
}
if(n!=0)
{
*pBuff64++=Base64Encode[n];
}
if(iLen%3==2)
//如果源字符串長度不是3的倍數要用'='補全
{
*pBuff64=
'=';
}
else
if(iLen%3==1)
{
*pBuff64++=
'=';
*pBuff64=
'=';
}
}
void CSendMail::AddFilePath(
char * pcFilePath)
//添加附件路徑
{
if(pcFilePath==NULL)
{
return;
}
int i;
char* temp;
for(i=0;i<m_pcFilePathList.GetCount();i++)
{
temp=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));
if(strcmp(pcFilePath,temp)==0)
//如果已經存在就不用再添加了
{
return;
}
}
m_pcFilePathList.AddTail(pcFilePath);
}
void CSendMail::DeleteFilePath(
char* pcFilePath)
//刪除附件路徑
{
int i;
char* temp;
for(i=0;i<m_pcFilePathList.GetCount();i++)
{
temp=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));
if(strcmp(temp,pcFilePath)==0)
//找到並刪除它,如果沒找到就算了
{
m_pcFilePathList.RemoveAt(m_pcFilePathList.FindIndex(i));
delete[] temp;
return;
}
}
}
void CSendMail::DeleteAllPath(
void)
{
m_pcFilePathList.RemoveAll();
}
int CSendMail::GetFileData(
char* FilePath)
{
m_pcFileBuff=NULL;
if(FilePath==NULL)
{
return 0;
}
CFile f;
int len;
USES_CONVERSION;
if(!f.Open(A2W(FilePath),CFile::modeRead|CFile::modeNoTruncate|CFile::typeBinary))
{
return 0;
}
len=(
int)f.GetLength();
m_pcFileBuff=
new
char[len+1];
memset(m_pcFileBuff,0,len+1);
f.Read(m_pcFileBuff,len);
f.Close();
return len;
}
void CSendMail::GetFileName(
char* fileName,
char* filePath)
{
if(filePath==NULL || fileName==NULL)
{
return;
}
int i;
for(i=0;i<(
int)strlen(filePath);i++)
{
if(filePath[strlen(filePath)-1-i]==
'\\')
{
memcpy(fileName,&filePath[strlen(filePath)-i],i);
return;
}
}
}
bool CSendMail::CReateSocket(SOCKET &sock)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return
false;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 )
{
WSACleanup( );
return
false;
}
sock = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if (sock == INVALID_SOCKET)
{
return
false;
}
sockaddr_in servaddr;
memset(&servaddr,0,
sizeof(sockaddr_in));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(25);
//發郵件一般都是25端口
if(m_sMailInfo.m_pcIPName==
"")
{
servaddr.sin_addr.s_addr = inet_addr(m_sMailInfo.m_pcIPAddr);
//直接使用IP地址
}
else
{
struct hostent *hp=gethostbyname(m_sMailInfo.m_pcIPName);
//使用名稱
servaddr.sin_addr.s_addr=*(
int*)(*hp->h_addr_list);
}
int ret = connect(sock,(sockaddr*)&servaddr,
sizeof(servaddr));
//建立連接
if (ret == SOCKET_ERROR)
{
return
false;
}
return
true;
}
bool CSendMail::Logon(SOCKET &sock)
{
recv(sock,m_cReceiveBuff,1024,0);
memset(m_cSendBuff,0,
sizeof(m_cSendBuff));
sprintf_s(m_cSendBuff,
"HELO []\r\n");
send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
//開始會話
recv(sock,m_cReceiveBuff,1024,0);
if(m_cReceiveBuff[0]!=
'2' || m_cReceiveBuff[1]!=
'5' || m_cReceiveBuff[2]!=
'0')
{
return
false;
}
memset(m_cSendBuff,0,
sizeof(m_cSendBuff));
sprintf_s(m_cSendBuff,
"AUTH LOGIN\r\n");
send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
//請求登錄
recv(sock,m_cReceiveBuff,1024,0);
if(m_cReceiveBuff[0]!=
'3' || m_cReceiveBuff[1]!=
'3' || m_cReceiveBuff[2]!=
'4')
{
return
false;
}
memset(m_cSendBuff,0,
sizeof(m_cSendBuff));
Char2Base64(m_cSendBuff,m_sMailInfo.m_pcUserName,strlen(m_sMailInfo.m_pcUserName));
m_cSendBuff[strlen(m_cSendBuff)]=
'\r';
m_cSendBuff[strlen(m_cSendBuff)]=
'\n';
send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
//發送用戶名
recv(sock,m_cReceiveBuff,1024,0);
if(m_cReceiveBuff[0]!=
'3' || m_cReceiveBuff[1]!=
'3' || m_cReceiveBuff[2]!=
'4')
{
return
false;
}
memset(m_cSendBuff,0,
sizeof(m_cSendBuff));
Char2Base64(m_cSendBuff,m_sMailInfo.m_pcUserPassWord,strlen(m_sMailInfo.m_pcUserPassWord));
m_cSendBuff[strlen(m_cSendBuff)]=
'\r';
m_cSendBuff[strlen(m_cSendBuff)]=
'\n';
send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
//發送用戶密碼
recv(sock,m_cReceiveBuff,1024,0);
if(m_cReceiveBuff[0]!=
'2' || m_cReceiveBuff[1]!=
'3' || m_cReceiveBuff[2]!=
'5')
{
return
false;
}
return
true;
//登錄成功
}
bool CSendMail::SendHead(SOCKET &sock)
{
int rt;
memset(m_cSendBuff,0,
sizeof(m_cSendBuff));
sprintf_s(m_cSendBuff,
"MAIL FROM:<%s>\r\n",m_sMailInfo.m_pcSender);
rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
if(rt!=strlen(m_cSendBuff))
{
return
false;
}
recv(sock,m_cReceiveBuff,1024,0);
memset(m_cSendBuff,0,
sizeof(m_cSendBuff));
sprintf_s(m_cSendBuff,
"RCPT TO:<%s>\r\n",m_sMailInfo.m_pcReceiver);
rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
if(rt!=strlen(m_cSendBuff))
{
return
false;
}
recv(sock,m_cReceiveBuff,1024,0);
memset(m_cSendBuff,0,
sizeof(m_cSendBuff));
memcpy(m_cSendBuff,
"DATA\r\n",strlen(
"DATA\r\n"));
rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
if(rt!=strlen(m_cSendBuff))
{
return
false;
}
recv(sock,m_cReceiveBuff,1024,0);
memset(m_cSendBuff,0,
sizeof(m_cSendBuff));
sprintf_s(m_cSendBuff,
"From:\"%s\"<%s>\r\n",m_sMailInfo.m_pcSenderName,m_sMailInfo.m_pcSender);
sprintf_s(&m_cSendBuff[strlen(m_cSendBuff)],150,
"To:\"INVT.COM.CN\"<%s>\r\n",m_sMailInfo.m_pcReceiver);
sprintf_s(&m_cSendBuff[strlen(m_cSendBuff)],150,
"Subject:%s\r\nMime-Version: 1.0\r\nContent-Type: multipart/mixed; boundary=\"INVT\"\r\n\r\n",m_sMailInfo.m_pcTitle);
rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
if(rt!=strlen(m_cSendBuff))
{
return
false;
}
return
true;
}
bool CSendMail::SendTextBody(SOCKET &sock)
{
int rt;
memset(m_cSendBuff,0,
sizeof(m_cSendBuff));
sprintf_s(m_cSendBuff,
"--INVT\r\nContent-Type: text/plain;\r\n charset=\"gb2312\"\r\n\r\n%s\r\n\r\n",m_sMailInfo.m_pcBody);
rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
if(rt!=strlen(m_cSendBuff))
{
return
false;
}
else
{
return
true;
}
}
bool CSendMail::SendFileBody(SOCKET &sock)
{
int i;
char* filePath;
int rt;
int len;
int pt=0;
char fileName[128];
for(i=0;i<m_pcFilePathList.GetCount();i++)
{
pt=0;
memset(fileName,0,128);
filePath=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));
len=GetFileData(filePath);
GetFileName(fileName,filePath);
sprintf_s(m_cSendBuff,
"--INVT\r\nContent-Type: application/octet-stream;\r\n name=\"%s\"\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment;\r\n filename=\"%s\"\r\n\r\n",fileName,fileName);
send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
while (pt<len)
{
memset(m_cSendBuff,0,
sizeof(m_cSendBuff));
Char2Base64(m_cSendBuff,&m_pcFileBuff[pt],min(len-pt,3000));
m_cSendBuff[strlen(m_cSendBuff)]=
'\r';
m_cSendBuff[strlen(m_cSendBuff)]=
'\n';
rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
pt+=min(len-pt,3000);
if(rt!=strlen(m_cSendBuff))
{
return
false;
}
}
if(len!=0)
{
delete [] m_pcFileBuff;
}
}
return
true;
}
bool CSendMail::SendEnd(SOCKET &sock)
{
sprintf_s(m_cSendBuff,
"--INVT--\r\n.\r\n");
send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
sprintf_s(m_cSendBuff,
"QUIT\r\n");
send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
closesocket(sock);
WSACleanup();
return
true;
}
bool CSendMail::SendMail(sMailInfo &smailInfo)
{
memcpy(&m_sMailInfo,&smailInfo,
sizeof(smailInfo));
if(m_sMailInfo.m_pcBody==NULL
|| m_sMailInfo.m_pcIPAddr==NULL
|| m_sMailInfo.m_pcIPName==NULL
|| m_sMailInfo.m_pcReceiver==NULL
|| m_sMailInfo.m_pcSender==NULL
|| m_sMailInfo.m_pcSenderName==NULL
|| m_sMailInfo.m_pcTitle==NULL
|| m_sMailInfo.m_pcUserName==NULL
|| m_sMailInfo.m_pcUserPassWord==NULL)
{
return
false;
}
SOCKET sock;
if(!CReateSocket(sock))
//建立連接
{
return
false;
}
if(!Logon(sock))
//登錄郵箱
{
return
false;
}
if(!SendHead(sock))
//發送郵件頭
{
return
false;
}
if(!SendTextBody(sock))
//發送郵件文本部分
{
return
false;
}
if(!SendFileBody(sock))
//發送附件
{
return
false;
}
if(!SendEnd(sock))
//結束郵件,並關閉sock
{
return
false;
}
return
true;
}
×
注意!
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。
郵件正文及其附件的發送的C++實現
郵件正文及其附件的發送的C++實現
C++發送郵件和附件(轉)
linux c/c++ 發送郵件程序的附件問題
SMTP VS C++實現向多人發送郵件,可帶多個附件
C# 帶附件郵件發送(支持多附件)
C#發送帶附件的郵件
c# 發送郵件、附件
郵件發送后附件名稱或下載附件名稱是亂碼的解決(C++)
C#發送帶附件的郵件的代碼
粤ICP备14056181号
© 2014-2021 ITdaan.com
×
收藏本文
添加到收藏夹 *