C++发送邮件和附件

c++socketnulldelete服务器stream

头文件

[cpp] view plaincopy

  1. /***********************************************************************
  2. *发送邮件模块头文件
  3. *可以发送文本和附件(支持多个附件一起发送)
  4. *************************************************************************/
  5. #pragma once
  6. struct sMailInfo //邮件信息
  7. {
  8. char*   m_pcUserName;//用户登录邮箱的名称
  9. char*   m_pcUserPassWord;//用户登录邮箱的密码
  10. char*   m_pcSenderName;//用户发送时显示的名称
  11. char*   m_pcSender;//发送者的邮箱地址
  12. char*   m_pcReceiver;//接收者的邮箱地址
  13. char*   m_pcTitle;//邮箱标题
  14. char*   m_pcBody;//邮件文本正文
  15. char*   m_pcIPAddr;//服务器的IP
  16. char*   m_pcIPName;//服务器的名称(IP与名称二选一,优先取名称)
  17. sMailInfo(){memset(this,0,sizeof(sMailInfo));}
  18. };
  19. class CSendMail
  20. {
  21. public:
  22. CSendMail(void);
  23. ~CSendMail(void);
  24. public:
  25. bool SendMail(sMailInfo &smailInfo);//发送邮件,需要在发送的时候初始化邮件信息
  26. void AddFilePath(char * pcFilePath);//添加附件的决定路径到附件列表中
  27. void DeleteFilePath(char* pcFilePath);//删除附件路径,如果有的话
  28. void DeleteAllPath(void);//删除全部附件的路径
  29. protected:
  30. void GetFileName(char* fileName,char* filePath);//从附件的路径中获取文件名称
  31. void Char2Base64(char* pBuff64,char* pSrcBuff,int iLen);//把char类型转换成Base64类型
  32. bool  CReateSocket(SOCKET &sock);//建立socket连接
  33. bool Logon(SOCKET &sock);//登录邮箱,主要进行发邮件前的准备工作
  34. int GetFileData(char* FilePath);//由文件路径获取附件内容
  35. bool SendHead(SOCKET &sock);//发送邮件头
  36. bool SendTextBody(SOCKET &sock);//发送邮件文本正文
  37. bool SendFileBody(SOCKET &sock);//发送邮件附件
  38. bool SendEnd(SOCKET &sock);//发送邮件结尾
  39. protected:
  40. CList<char*,char*> m_pcFilePathList;//记录附件路径
  41. char  m_cSendBuff[4096];//发送缓冲区
  42. char  m_cReceiveBuff[1024];
  43. char* m_pcFileBuff;//指向附件内容
  44. sMailInfo m_sMailInfo;
  45. };

模块实现文件

[cpp] view plaincopy

  1. /************************************************************************
  2. * 发送邮件模块
  3. *可以发送文本和附件(支持多个附件一起发送)
  4. *Date:2011-12-01
  5. ************************************************************************/
  6. #include "StdAfx.h"
  7. #include "SendMail.h"
  8. #include "winsock2.h"
  9. #pragma comment(lib,"WSOCK32")
  10. CSendMail::CSendMail(void)
  11. {
  12. m_pcFileBuff=NULL;
  13. memset(m_cSendBuff,0,sizeof(m_cSendBuff));
  14. memset(m_cReceiveBuff,0,sizeof(m_cReceiveBuff));
  15. }
  16. CSendMail::~CSendMail(void)
  17. {
  18. DeleteAllPath();
  19. }
  20. void CSendMail::Char2Base64(char* pBuff64,char* pSrcBuff,int iLen)
  21. {
  22. //1   1   1   1   1   1   1   1
  23. // 分配给pBuff64  ↑ 分配给pBuff64+1
  24. //         point所在的位置
  25. static char Base64Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//base64所映射的字符表
  26. int point;//每一个源字符拆分的位置,可取2,4,6;初始为2
  27. point=2;
  28. int i;
  29. int iIndex;//base64字符的索引
  30. char n=0;//上一个源字符的残留值
  31. for(i=0;i<iLen;i++)
  32. {
  33. if(point==2)
  34. {
  35. iIndex=((*pSrcBuff)>>point)&0x3f;//取得pSrcBuff的高point位
  36. }
  37. else if (point==4)
  38. {
  39. iIndex=((*pSrcBuff)>>point)&0xf;//取得pSrcBuff的高point位
  40. }
  41. else if(point==6)
  42. {
  43. iIndex=((*pSrcBuff)>>point)&0x3;//取得pSrcBuff的高point位
  44. }
  45. iIndex+=n;//与pSrcBuff-1的低point结合组成Base64的索引
  46. *pBuff64++=Base64Encode[iIndex];//由索引表得到pBuff64
  47. n=((*pSrcBuff)<<(6-point));//计算源字符中的残留值
  48. n=n&0x3f;//确保n的最高两位为0
  49. point+=2;//源字符的拆分位置上升2
  50. if(point==8)//如果拆分位置为8说明pSrcBuff有6位残留,可以组成一个完整的Base64字符,所以直接再组合一次
  51. {
  52. iIndex=(*pSrcBuff)&0x3f;//提取低6位,这就是索引了
  53. *pBuff64++=Base64Encode[iIndex];//
  54. n=0;//残留值为0
  55. point=2;//拆分位置设为2
  56. }
  57. pSrcBuff++;
  58. }
  59. if(n!=0)
  60. {
  61. *pBuff64++=Base64Encode[n];
  62. }
  63. if(iLen%3==2)//如果源字符串长度不是3的倍数要用‘=‘补全
  64. {
  65. *pBuff64=‘=‘;
  66. }
  67. else if(iLen%3==1)
  68. {
  69. *pBuff64++=‘=‘;
  70. *pBuff64=‘=‘;
  71. }
  72. }
  73. void CSendMail::AddFilePath(char * pcFilePath)//添加附件路径
  74. {
  75. if(pcFilePath==NULL)
  76. {
  77. return;
  78. }
  79. int i;
  80. char* temp;
  81. for(i=0;i<m_pcFilePathList.GetCount();i++)
  82. {
  83. temp=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));
  84. if(strcmp(pcFilePath,temp)==0)//如果已经存在就不用再添加了
  85. {
  86. return;
  87. }
  88. }
  89. m_pcFilePathList.AddTail(pcFilePath);
  90. }
  91. void CSendMail::DeleteFilePath(char* pcFilePath)//删除附件路径
  92. {
  93. int i;
  94. char* temp;
  95. for(i=0;i<m_pcFilePathList.GetCount();i++)
  96. {
  97. temp=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));
  98. if(strcmp(temp,pcFilePath)==0)//找到并删除它,如果没找到就算了
  99. {
  100. m_pcFilePathList.RemoveAt(m_pcFilePathList.FindIndex(i));
  101. delete[] temp;
  102. return;
  103. }
  104. }
  105. }
  106. void CSendMail::DeleteAllPath(void)
  107. {
  108. m_pcFilePathList.RemoveAll();
  109. }
  110. int CSendMail::GetFileData(char* FilePath)
  111. {
  112. m_pcFileBuff=NULL;
  113. if(FilePath==NULL)
  114. {
  115. return 0;
  116. }
  117. CFile f;
  118. int len;
  119. USES_CONVERSION;
  120. if(!f.Open(A2W(FilePath),CFile::modeRead|CFile::modeNoTruncate|CFile::typeBinary))
  121. {
  122. return 0;
  123. }
  124. len=(int)f.GetLength();
  125. m_pcFileBuff=new char[len+1];
  126. memset(m_pcFileBuff,0,len+1);
  127. f.Read(m_pcFileBuff,len);
  128. f.Close();
  129. return len;
  130. }
  131. void CSendMail::GetFileName(char* fileName,char* filePath)
  132. {
  133. if(filePath==NULL || fileName==NULL)
  134. {
  135. return;
  136. }
  137. int i;
  138. for(i=0;i<(int)strlen(filePath);i++)
  139. {
  140. if(filePath[strlen(filePath)-1-i]==‘\\‘)
  141. {
  142. memcpy(fileName,&filePath[strlen(filePath)-i],i);
  143. return;
  144. }
  145. }
  146. }
  147. bool CSendMail::CReateSocket(SOCKET &sock)
  148. {
  149. WORD wVersionRequested;
  150. WSADATA wsaData;
  151. int err;
  152. wVersionRequested = MAKEWORD( 2, 2 );
  153. err = WSAStartup( wVersionRequested, &wsaData );
  154. if ( err != 0 )
  155. {
  156. return false;
  157. }
  158. if ( LOBYTE( wsaData.wVersion ) != 2 ||
  159. HIBYTE( wsaData.wVersion ) != 2 )
  160. {
  161. WSACleanup( );
  162. return false;
  163. }
  164. sock = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
  165. if (sock == INVALID_SOCKET)
  166. {
  167. return false;
  168. }
  169. sockaddr_in servaddr;
  170. memset(&servaddr,0,sizeof(sockaddr_in));
  171. servaddr.sin_family = AF_INET;
  172. servaddr.sin_port = htons(25);//发邮件一般都是25端口
  173. if(m_sMailInfo.m_pcIPName=="")
  174. {
  175. servaddr.sin_addr.s_addr = inet_addr(m_sMailInfo.m_pcIPAddr);//直接使用IP地址
  176. }
  177. else
  178. {
  179. struct hostent *hp=gethostbyname(m_sMailInfo.m_pcIPName);//使用名称
  180. servaddr.sin_addr.s_addr=*(int*)(*hp->h_addr_list);
  181. }
  182. int ret = connect(sock,(sockaddr*)&servaddr,sizeof(servaddr));//建立连接
  183. if (ret == SOCKET_ERROR)
  184. {
  185. return false;
  186. }
  187. return true;
  188. }
  189. bool CSendMail::Logon(SOCKET &sock)
  190. {
  191. recv(sock,m_cReceiveBuff,1024,0);
  192. memset(m_cSendBuff,0,sizeof(m_cSendBuff));
  193. sprintf_s(m_cSendBuff,"HELO []\r\n");
  194. send(sock,m_cSendBuff,strlen(m_cSendBuff),0);//开始会话
  195. recv(sock,m_cReceiveBuff,1024,0);
  196. if(m_cReceiveBuff[0]!=‘2‘ || m_cReceiveBuff[1]!=‘5‘ || m_cReceiveBuff[2]!=‘0‘)
  197. {
  198. return false;
  199. }
  200. memset(m_cSendBuff,0,sizeof(m_cSendBuff));
  201. sprintf_s(m_cSendBuff,"AUTH LOGIN\r\n");
  202. send(sock,m_cSendBuff,strlen(m_cSendBuff),0);//请求登录
  203. recv(sock,m_cReceiveBuff,1024,0);
  204. if(m_cReceiveBuff[0]!=‘3‘ || m_cReceiveBuff[1]!=‘3‘ || m_cReceiveBuff[2]!=‘4‘)
  205. {
  206. return false;
  207. }
  208. memset(m_cSendBuff,0,sizeof(m_cSendBuff));
  209. Char2Base64(m_cSendBuff,m_sMailInfo.m_pcUserName,strlen(m_sMailInfo.m_pcUserName));
  210. m_cSendBuff[strlen(m_cSendBuff)]=‘\r‘;
  211. m_cSendBuff[strlen(m_cSendBuff)]=‘\n‘;
  212. send(sock,m_cSendBuff,strlen(m_cSendBuff),0);//发送用户名
  213. recv(sock,m_cReceiveBuff,1024,0);
  214. if(m_cReceiveBuff[0]!=‘3‘ || m_cReceiveBuff[1]!=‘3‘ || m_cReceiveBuff[2]!=‘4‘)
  215. {
  216. return false;
  217. }
  218. memset(m_cSendBuff,0,sizeof(m_cSendBuff));
  219. Char2Base64(m_cSendBuff,m_sMailInfo.m_pcUserPassWord,strlen(m_sMailInfo.m_pcUserPassWord));
  220. m_cSendBuff[strlen(m_cSendBuff)]=‘\r‘;
  221. m_cSendBuff[strlen(m_cSendBuff)]=‘\n‘;
  222. send(sock,m_cSendBuff,strlen(m_cSendBuff),0);//发送用户密码
  223. recv(sock,m_cReceiveBuff,1024,0);
  224. if(m_cReceiveBuff[0]!=‘2‘ || m_cReceiveBuff[1]!=‘3‘ || m_cReceiveBuff[2]!=‘5‘)
  225. {
  226. return false;
  227. }
  228. return true;//登录成功
  229. }
  230. bool CSendMail::SendHead(SOCKET &sock)
  231. {
  232. int rt;
  233. memset(m_cSendBuff,0,sizeof(m_cSendBuff));
  234. sprintf_s(m_cSendBuff,"MAIL FROM:<%s>\r\n",m_sMailInfo.m_pcSender);
  235. rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
  236. if(rt!=strlen(m_cSendBuff))
  237. {
  238. return false;
  239. }
  240. recv(sock,m_cReceiveBuff,1024,0);
  241. memset(m_cSendBuff,0,sizeof(m_cSendBuff));
  242. sprintf_s(m_cSendBuff,"RCPT TO:<%s>\r\n",m_sMailInfo.m_pcReceiver);
  243. rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
  244. if(rt!=strlen(m_cSendBuff))
  245. {
  246. return false;
  247. }
  248. recv(sock,m_cReceiveBuff,1024,0);
  249. memset(m_cSendBuff,0,sizeof(m_cSendBuff));
  250. memcpy(m_cSendBuff,"DATA\r\n",strlen("DATA\r\n"));
  251. rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
  252. if(rt!=strlen(m_cSendBuff))
  253. {
  254. return false;
  255. }
  256. recv(sock,m_cReceiveBuff,1024,0);
  257. memset(m_cSendBuff,0,sizeof(m_cSendBuff));
  258. sprintf_s(m_cSendBuff,"From:\"%s\"<%s>\r\n",m_sMailInfo.m_pcSenderName,m_sMailInfo.m_pcSender);
  259. sprintf_s(&m_cSendBuff[strlen(m_cSendBuff)],150,"To:\"INVT.COM.CN\"<%s>\r\n",m_sMailInfo.m_pcReceiver);
  260. 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);
  261. rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
  262. if(rt!=strlen(m_cSendBuff))
  263. {
  264. return false;
  265. }
  266. return true;
  267. }
  268. bool CSendMail::SendTextBody(SOCKET &sock)
  269. {
  270. int rt;
  271. memset(m_cSendBuff,0,sizeof(m_cSendBuff));
  272. 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);
  273. rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
  274. if(rt!=strlen(m_cSendBuff))
  275. {
  276. return false;
  277. }
  278. else
  279. {
  280. return true;
  281. }
  282. }
  283. bool CSendMail::SendFileBody(SOCKET &sock)
  284. {
  285. int i;
  286. char* filePath;
  287. int rt;
  288. int len;
  289. int pt=0;
  290. char fileName[128];
  291. for(i=0;i<m_pcFilePathList.GetCount();i++)
  292. {
  293. pt=0;
  294. memset(fileName,0,128);
  295. filePath=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));
  296. len=GetFileData(filePath);
  297. GetFileName(fileName,filePath);
  298. 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);
  299. send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
  300. while (pt<len)
  301. {
  302. memset(m_cSendBuff,0,sizeof(m_cSendBuff));
  303. Char2Base64(m_cSendBuff,&m_pcFileBuff[pt],min(len-pt,3000));
  304. m_cSendBuff[strlen(m_cSendBuff)]=‘\r‘;
  305. m_cSendBuff[strlen(m_cSendBuff)]=‘\n‘;
  306. rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
  307. pt+=min(len-pt,3000);
  308. if(rt!=strlen(m_cSendBuff))
  309. {
  310. return false;
  311. }
  312. }
  313. if(len!=0)
  314. {
  315. delete [] m_pcFileBuff;
  316. }
  317. }
  318. return true;
  319. }
  320. bool CSendMail::SendEnd(SOCKET &sock)
  321. {
  322. sprintf_s(m_cSendBuff,"--INVT--\r\n.\r\n");
  323. send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
  324. sprintf_s(m_cSendBuff,"QUIT\r\n");
  325. send(sock,m_cSendBuff,strlen(m_cSendBuff),0);
  326. closesocket(sock);
  327. WSACleanup();
  328. return true;
  329. }
  330. bool CSendMail::SendMail(sMailInfo &smailInfo)
  331. {
  332. memcpy(&m_sMailInfo,&smailInfo,sizeof(smailInfo));
  333. if(m_sMailInfo.m_pcBody==NULL
  334. || m_sMailInfo.m_pcIPAddr==NULL
  335. || m_sMailInfo.m_pcIPName==NULL
  336. || m_sMailInfo.m_pcReceiver==NULL
  337. || m_sMailInfo.m_pcSender==NULL
  338. || m_sMailInfo.m_pcSenderName==NULL
  339. || m_sMailInfo.m_pcTitle==NULL
  340. || m_sMailInfo.m_pcUserName==NULL
  341. || m_sMailInfo.m_pcUserPassWord==NULL)
  342. {
  343. return false;
  344. }
  345. SOCKET sock;
  346. if(!CReateSocket(sock))//建立连接
  347. {
  348. return false;
  349. }
  350. if(!Logon(sock))//登录邮箱
  351. {
  352. return false;
  353. }
  354. if(!SendHead(sock))//发送邮件头
  355. {
  356. return false;
  357. }
  358. if(!SendTextBody(sock))//发送邮件文本部分
  359. {
  360. return false;
  361. }
  362. if(!SendFileBody(sock))//发送附件
  363. {
  364. return false;
  365. }
  366. if(!SendEnd(sock))//结束邮件,并关闭sock
  367. {
  368. return false;
  369. }
  370. return true;
  371. }
时间: 2024-10-26 21:27:41

C++发送邮件和附件的相关文章

python发送邮件和附件

发送邮件的时候,需要发送人,收件人,和一台邮件服务器,这里使用python发送一个邮件,主要需要引入smtplib和email库.下面是源码,粘贴即可用: #!/usr/bin/env python3 # coding: utf-8 import smtplib import time import sys from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart # 发送邮件 def

Java发送邮件(带附件)

实现java发送邮件的过程大体有以下几步: 准备一个properties文件,该文件中存放SMTP服务器地址等参数. 利用properties创建一个Session对象 利用Session创建Message对象,然后设置邮件主题和正文 利用Transport对象发送邮件 需要的jar有2个:activation.jar和mail.jar 直接看个demo代码 #----------------这两个是构建session必须的字段----------#smtp服务器mail.smtp.host=s

linux发送邮件和附件---mail,mailx

安装的包 [[email protected] ~]# rpm -qa|grep mail procmail-3.22-25.1.el6_5.1.x86_64 mailcap-2.1.31-2.el6.noarch libreport-plugin-mailx-2.0.9-19.el6.centos.x86_64 mailx-12.4-8.el6_6.x86_64 [[email protected] ~]# 如果没有装的话,要么找iso文件中的rpm包,也可以直接yum. [[email pr

centos 使用mutt发送邮件带附件

1.安装mutt工具 yum install -y mutt 2.使用mutt发邮件并带附件echo "统计日志" | /usr/bin/mutt -s "统计日志" -a /data/openRoom/openRoom.log -- "[email protected]" -c "[email protected]"注解:echo "统计日志" :邮件正文-s "统计日志" : 邮件主

c# 发送邮件、附件

WinForm窗体代码如下: <span style="font-size:14px;">using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; <span s

Oracle发送邮件带附件

这两天一直在弄oracle发送邮件的事情,在网上找了一堆代码,但是需要按照银行政策调整.以下说说具体实现过程:先贴过程: 1 CREATE OR REPLACE PROCEDURE SMT_SEND_MAIL(P_TXT VARCHAR2, 2 P_SUB VARCHAR2, 3 P_SENDOR VARCHAR2, 4 P_RECEIVER VARCHAR2, 5 P_SERVER VARCHAR2, 6 P_PORT NUMBER DEFAULT 25, 7 P_NEED_SMTP INT

python3 发送邮件携带附件(可携带多个不同格式的附件)

最近在学习python,刚刚看完python3使用SMTP发送邮件,简单小节下. 要了解SMTP的可以自行去百度,这里不做解释. 使用SMTP发送有邮件前要确保发件人的邮箱已开启SMTP服务.若发件人邮箱已开启此服务可跳过此教程直接参考代码. 一.163邮箱开启SMTP方式 1.登陆163邮箱网页版,进入"POP3/SMTP/IMAP"页面,开启smtp服务,一般默认开启, 直接去生成授权码即可. 2.生成客户端授权码,进入"客户端授权密码"页面,开启客户端授权码.

ASP.NET 实现发送邮件 + 多个收件人 + 多个附件

最近项目中需要实现发送邮件+添加附件的功能,于是又学习了一下System.Net.Mail.MailMessage和System.Net.Mail.SmtpClient等几个.Net中发邮件的几个类,根据网上的一些代码,做了一个小Demo分享一下. 界面效果 老规矩,还是先看效果,以下为发送邮件的界面: 发件人输入发送人的邮箱.密码: 收件人栏目可输入多个收件人,多个收件人之间需要用英文状态下的分号" ; "来隔开(当然这只是一种方式,还可以根据需求设计输入联系人的方式,如从通讯录选择

Java 发送邮件

一 邮件的发送过程 ① 发件人编辑邮件 ② 邮件发送至发送账号所有的SMTP服务器 ③ 如果发送账号和接收账号不在同一SMTP服务器,发送账号所属的服务器负责将邮件发至收件人所属SMTP服务器 ④ 收件人查看邮件时,收件人所属服务器把邮件传给收件人的客户端 从而使用Java开发程序所需做的事情:创建和编辑邮件,发送邮件至发件人所属服务器 二 邮件的基本组成内容 如上图所示,邮件的主要组成部分有 发件人,收件人,抄送,密送,主题,附件,正文 正文是用富文本编辑器编辑,即可以是无格式文本,也可以是h