#include "stdafx.h"
#include "Smtp.h"
#include <iostream>
#include <fstream>
using namespace std;
/*base64采用别人的编码,不过,这不是重点,重点是我完成了我的一个比较好的邮件发送客户端*/
char* CSmtp::base64Encode(char const* origSigned, unsigned origLength)
{
unsigned char const* orig = (unsigned char const*)origSigned; // in case any input bytes have the MSB set
if (orig == NULL) return NULL;
unsigned const numOrig24BitValues = origLength / 3;
bool havePadding = origLength > numOrig24BitValues * 3;
bool havePadding2 = origLength == numOrig24BitValues * 3 + 2;
unsigned const numResultBytes = 4 * (numOrig24BitValues + havePadding);
char* result = new char[numResultBytes + 3]; // allow for trailing '/0'
// Map each full group of 3 input bytes into 4 output base-64 characters:
unsigned i;
for (i = 0; i < numOrig24BitValues; ++i)
{
result[4 * i + 0] = base64Char[(orig[3 * i] >> 2) & 0x3F];
result[4 * i + 1] = base64Char[(((orig[3 * i] & 0x3) << 4) | (orig[3 * i + 1] >> 4)) & 0x3F];
result[4 * i + 2] = base64Char[((orig[3 * i + 1] << 2) | (orig[3 * i + 2] >> 6)) & 0x3F];
result[4 * i + 3] = base64Char[orig[3 * i + 2] & 0x3F];
}
// Now, take padding into account. (Note: i == numOrig24BitValues)
if (havePadding)
{
result[4 * i + 0] = base64Char[(orig[3 * i] >> 2) & 0x3F];
if (havePadding2)
{
result[4 * i + 1] = base64Char[(((orig[3 * i] & 0x3) << 4) | (orig[3 * i + 1] >> 4)) & 0x3F];
result[4 * i + 2] = base64Char[(orig[3 * i + 1] << 2) & 0x3F];
}
else
{
result[4 * i + 1] = base64Char[((orig[3 * i] & 0x3) << 4) & 0x3F];
result[4 * i + 2] = '=';
}
result[4 * i + 3] = '=';
}
result[numResultBytes] = '\0';
return result;
}
CSmtp::CSmtp(void)
{
setlocale(LC_ALL,"Chinese-simplified");
this->content = "";
this->port = 25;
this->user = "";
this->pass = "";
this->targetAddr = "";
this->title = "";
this->domain = "";
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 1);
err = WSAStartup(wVersionRequested, &wsaData);
this->sockClient = 0;
}
CSmtp::~CSmtp(void)
{
DeleteAllAttachment();
closesocket(sockClient);
WSACleanup();
}
CSmtp::CSmtp(
int port,
string srvDomain,
string userName,
string password,
string targetEmail,
string emailTitle,
string content
)
{
setlocale(LC_ALL,"Chinese-simplified");
this->content = content;
this->port = port;
this->user = userName;
this->pass = password;
this->targetAddr = targetEmail;
this->title = emailTitle;
this->domain = srvDomain;
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 1);
err = WSAStartup(wVersionRequested, &wsaData);
this->sockClient = 0;
}
BOOL CSmtp::CreateConn()
{
//为建立socket对象做准备,初始化环境
SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0); //建立socket对象
SOCKADDR_IN addrSrv;
HOSTENT* pHostent;
pHostent = gethostbyname(domain.c_str()); //得到有关于域名的信息
addrSrv.sin_addr.S_un.S_addr = *((DWORD *)pHostent->h_addr_list[0]); //得到smtp服务器的网络字节序的ip地址
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(port);
int err = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); //向服务器发送请求
if(err != 0)
{
return FALSE;
//printf("链接失败\n");
}
this->sockClient = sockClient;
if (FALSE == Recv())
{
return FALSE;
}
return TRUE;
}
BOOL CSmtp::Send(string &message)
{
int err = send(sockClient, message.c_str(), message.length(), 0);
if (err == SOCKET_ERROR)
{
return FALSE;
}
cout << message << endl;
return TRUE;
}
BOOL CSmtp::Recv()
{
memset(buff, 0, sizeof(char)* (MAXLEN + 1));
int err = recv(sockClient, buff, MAXLEN, 0); //接收数据
if (err == SOCKET_ERROR)
{
return FALSE;
}
buff[err] = '\0';
cout << buff << endl;
return TRUE;
}
int CSmtp::Login()
{
string sendBuff;
sendBuff = "EHLO ";
sendBuff += user;
sendBuff += "\r\n";
if (FALSE == Send(sendBuff) || FALSE == Recv()) //既接收也发送
{
return 1; /*1表示发送失败由于网络错误*/
}
sendBuff.empty();
sendBuff = "AUTH LOGIN\r\n";
if (FALSE == Send(sendBuff) || FALSE == Recv()) //请求登陆
{
return 1; /*1表示发送失败由于网络错误*/
}
sendBuff.empty();
int pos = user.find('@', 0);
sendBuff = user.substr(0, pos); //得到用户名
char *ecode;
/*在这里顺带扯一句,关于string类的length函数与C语言中的strlen函数的区别,strlen计算出来的长度,只到'\0'字符为止,而string::length()函数实际上返回的是string类中字符数组的大小,你自己可以测试一下,这也是为什么我下面不使用string::length()的原因*/
ecode = base64Encode(sendBuff.c_str(), strlen(sendBuff.c_str()));
sendBuff.empty();
sendBuff = ecode;
sendBuff += "\r\n";
delete []ecode;
if (FALSE == Send(sendBuff) || FALSE == Recv()) //发送用户名,并接收服务器的返回
{
return 1; /*错误码1表示发送失败由于网络错误*/
}
sendBuff.empty();
ecode = base64Encode(pass.c_str(), strlen(pass.c_str()));
sendBuff = ecode;
sendBuff += "\r\n";
delete []ecode;
if (FALSE == Send(sendBuff) || FALSE == Recv()) //发送用户密码,并接收服务器的返回
{
return 1; /*错误码1表示发送失败由于网络错误*/
}
if (NULL != strstr(buff, "550"))
{
return 2;/*错误码2表示用户名错误*/
}
if (NULL != strstr(buff, "535")) /*535是认证失败的返回*/
{
return 3; /*错误码3表示密码错误*/
}
return 0;
}
BOOL CSmtp::SendEmailHead() //发送邮件头部信息
{
string sendBuff;
sendBuff = "MAIL FROM: <" + user + ">\r\n";
if (FALSE == Send(sendBuff) || FALSE == Recv())
{
return FALSE; /*表示发送失败由于网络错误*/
}
sendBuff.empty();
sendBuff = "RCPT TO: <" + targetAddr + ">\r\n";
if (FALSE == Send(sendBuff) || FALSE == Recv())
{
return FALSE; /*表示发送失败由于网络错误*/
}
sendBuff.empty();
sendBuff = "DATA\r\n";
if (FALSE == Send(sendBuff) || FALSE == Recv())
{
return FALSE; //表示发送失败由于网络错误
}
sendBuff.empty();
FormatEmailHead(sendBuff);
if (FALSE == Send(sendBuff))
//发送完头部之后不必调用接收函数,因为你没有\r\n.\r\n结尾,服务器认为你没有发完数据,所以不会返回什么值
{
return FALSE; /*表示发送失败由于网络错误*/
}
return TRUE;
}
void CSmtp::FormatEmailHead(string &email)
{/*格式化要发送的内容*/
email = "From: ";
email += user;
email += "\r\n";
email += "To: ";
email += targetAddr;
email += "\r\n";
email += "Subject: ";
email += title;
email += "\r\n";
email += "MIME-Version: 1.0";
email += "\r\n";
email += "Content-Type: multipart/mixed;boundary=qwertyuiop";
email += "\r\n";
email += "\r\n";
}
BOOL CSmtp::SendTextBody() /*发送邮件文本*/
{
string sendBuff;
sendBuff = "--qwertyuiop\r\n";
sendBuff += "Content-Type: text/plain;";
sendBuff += "charset=\"gb2312\"\r\n\r\n";
sendBuff += content;
sendBuff += "\r\n\r\n";
return Send(sendBuff);
}
int CSmtp::SendAttachment_Ex() /*发送附件*/
{
for (list<FILEINFO *>::iterator pIter = listFile.begin(); pIter != listFile.end(); pIter++)
{
cout << "Attachment is sending ~~~~~" << endl;
cout << "Please be patient!" << endl;
string sendBuff;
sendBuff = "--qwertyuiop\r\n";
sendBuff += "Content-Type: application/octet-stream;\r\n";
sendBuff += " name=\"";
sendBuff += (*pIter)->fileName;
sendBuff += "\"";
sendBuff += "\r\n";
sendBuff += "Content-Transfer-Encoding: base64\r\n";
sendBuff += "Content-Disposition: attachment;\r\n";
sendBuff += " filename=\"";
sendBuff += (*pIter)->fileName;
sendBuff += "\"";
sendBuff += "\r\n";
sendBuff += "\r\n";
Send(sendBuff);
ifstream ifs((*pIter)->filePath,ios::in | ios::binary);
if (FALSE == ifs.is_open())
{
return 4; /*错误码4表示文件打开错误*/
}
char fileBuff[MAX_FILE_LEN];
char *chSendBuff;
memset(fileBuff, 0, sizeof(fileBuff));
/*文件使用base64加密传送*/
while (ifs.read(
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
Email究极最终版.rar (77个子文件)
Email
WSocket.h 1KB
Email.rc 7KB
Email.aps 44KB
stdafx.cpp 136B
7.eml 2KB
Release
7.eml 2KB
9.eml 508KB
Pop3.obj 18KB
Email.res 24KB
6.eml 2KB
stdafx.obj 1.84MB
Email.pch 13.81MB
Email.obj 469KB
BuildLog.htm 14KB
4.eml 9KB
8.eml 11KB
WSocket.obj 16KB
Email.exe.intermediate.manifest 874B
5.eml 12KB
Smtp.obj 599KB
mt.dep 67B
3.eml 2KB
1.eml 15KB
Email.exe 80KB
vc80.pdb 836KB
Email.pdb 3MB
EmailDlg.obj 523KB
vc80.idb 515KB
2.eml 13KB
Set.obj 31KB
Email.h 435B
Email.cpp 2KB
Set.cpp 3KB
6.eml 4KB
res
Email.ico 21KB
Email.rc2 361B
Email.vcproj.98C57B1AAC3D48A.Administrator.user 1KB
stdafx.h 2KB
Email.suo 48KB
Email.vcproj.418-085.Administrator.user 1KB
4.eml 33KB
Email.vcproj 6KB
EmailDlg.h 1KB
Smtp.cpp 11KB
8.eml 2KB
5.eml 33KB
3.eml 11KB
1.eml 12KB
Pop3.h 868B
Email.ncb 10.58MB
Smtp.h 2KB
resource.h 2KB
Pop3.cpp 4KB
EmailDlg.cpp 10KB
WSocket.cpp 3KB
Debug
Pop3.obj 19KB
Email.res 24KB
stdafx.obj 263KB
Email.pch 12.88MB
Email.obj 46KB
BuildLog.htm 7KB
Email.exe.embed.manifest 936B
WSocket.obj 15KB
Email.exe.intermediate.manifest 884B
Email.exe.embed.manifest.res 1000B
Smtp.obj 201KB
mt.dep 67B
Email.exe 144KB
vc80.pdb 836KB
Email.pdb 3.5MB
EmailDlg.obj 98KB
vc80.idb 867KB
Email.ilk 1.29MB
Set.obj 30KB
2.eml 10KB
Email.sln 874B
Set.h 536B
共 77 条
- 1
资源评论
weixin_44178089
- 粉丝: 2
- 资源: 2
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- AIS2024 valid
- 最入门的爬虫代码 python.docx
- 爬虫零基础入门-爬取天气预报.pdf
- 最通俗易懂的 MongoDB 非结构化文档存储数据库教程.zip
- 以mongodb为数据库的订单物流小项目.zip
- 腾讯云-mongodb数据库, 项目部署.zip
- 腾讯 APIJSON 的 MongoDB 数据库插件.zip
- 理解非关系型数据库和关系型数据库的区别.zip
- 操作简单的Mongodb网页web管理工具,基于Spring Boot2.0支持mongodb集群.zip
- tms-mongodb-web,提供访问mongodb数据的REST API和可灵活扩展的mongodb web 客户端.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功