C++发送邮件和附件
头文件
- /***********************************************************************
- *发送邮件模块头文件
- *可以发送文本和附件(支持多个附件一起发送)
- *************************************************************************/
- #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;
- };
模块实现文件
- /************************************************************************
- * 发送邮件模块
- *可以发送文本和附件(支持多个附件一起发送)
- *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++发送邮件和附件的更多相关文章
- SpringBoot 发送邮件和附件
作者:yizhiwaz 链接:www.jianshu.com/p/5eb000544dd7 源码:https://github.com/yizhiwazi/springboot-socks 其他文章: ...
- Spring 4 使用Freemarker模板发送邮件&添加附件
前言 Spring对Java的邮件发送提供了很好的支持,提供了超级简单的API,大大简化了Java邮件发送功能的开发. Spring对Email的支持是基于JavaMail API开发的,所以,我们在 ...
- python发送邮件及附件
今天给大伙说说python发送邮件,官方的多余的话自己去百度好了,还有一大堆文档说实话不到万不得已的时候一般人都不会去看,回归主题: 本人是mac如果没有按照依赖模块的请按照下面的截图安装 导入模块如 ...
- CentOS 7 使用外部邮箱 发送邮件和附件—mail,mailx
1.查看软件包是否安装 [root@localhost ~]# rpm -qa|grep mail mailx-12.5-12.el7_0.x86_64 javamail-1.4.6-8.el7.no ...
- linux 命令行发送邮件及附件
环境 本机安装sendmail了, 但是没有启动. 其他机器上有mail server, 并且已经把本机加到open relay列表中了, 可以通过该mail server发送邮件.做法如下:1. 安 ...
- Java发送邮件(带附件)
实现java发送邮件的过程大体有以下几步: 准备一个properties文件,该文件中存放SMTP服务器地址等参数. 利用properties创建一个Session对象 利用Session创建Mess ...
- c# 发送邮件、附件 分类: C# 2014-12-17 16:41 201人阅读 评论(0) 收藏
WinForm窗体代码如下: <span style="font-size:14px;">using System; using System.Collections. ...
- PHPMailer发送邮件中文附件名是乱码
可能使用了PHPMailer发送邮件的朋友带中文附件名时会出现乱码,下面我来介绍一个解决办法. 比如我们要发送的附件是"测试.txt",如果在添加附件的时候强制使用指定文件名的方式 ...
- 使用System.Net.Mail中的SMTP发送邮件(带附件)
System.Net.Mail 使用简单邮件传输协议SMTP异步发送邮件 想要实现SMTP发送邮件,你需要了解这些类 SmtpClient :使用配置文件设置来初始化 SmtpClient类的新实例. ...
随机推荐
- linux 监控系统缓存和cpu
a=`free |head -n 2 |tail -n 1 |awk '{print $7}'`if [ $a -ge 900000 ];then sync && echo 1 ...
- phpcms v9后台美化需要修改的部分整理
PHPcms后台登陆后的页面修改 Phpcms->modules->admin->templates->main.tpl.php 1,安全提示部分 <h6>< ...
- 动态改变数据库连接 in Entity Framework 5
今天把silverlight 升级到5,ADO.ENT EF也用NUGet升级到5.结果发现5下的EF默认没有4的那种分部方法了. 当然你可以把生成器的属性里面,生成代码的属性替换为default,默 ...
- Apache配置域名
Apache配置域名 在WIN下安装APACHE配置虚拟目录和UNIN下基本是一样的就是修改httpd.conf1:单个IP对应单个域名例如:www.phpunion.com对应192.168.1.1 ...
- yii 验证确认密码是否一致 【"compare",'compareAttribute'=>'password'】
array("surepassword","compare",'compareAttribute'=>'password','message'=>' ...
- python自动开发之第二十一天
一.请求周期 url> 路由 > 函数或类 > 返回字符串或者模板语言? 1.Form表单提交: 提交 -> url > 函数或类中的方法 - .... HttpResp ...
- [walkthrough] 在Asp.net MVC6 RC里使用NLog,并且把配置集成到config.json
说明一下:本文基于随visual studio 2015 RC公开的DNX1.0.0-beta4,git上最新的aspnet的开发版本已经发生了很大变化. 首先,理论部分看[汤姆大叔的博客] 解读AS ...
- 转:Gulp使用指南
原文来自于:http://www.techug.com/gulp Grunt靠边,全新的建构工具来了.Gulp的code-over-configuration不只让撰写任务(tasks)更加容易,也更 ...
- tomcat源码阅读
1 工具准备 需要SVN.Maven.JDK.Eclipse.Eclipse M2插件 2 下载源码及发布包 源码在这里:http://svn.apache.org/repos/a ...
- Truck History
poj1789:http://poj.org/problem?id=1789 题意大概是这样的:用一个7位的string代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数.一 ...