C++实现邮件群发的方法
这篇文章主要介绍了C++实现邮件群发的方法,较为详细的分析了邮件发送的原理与C++相关实现技巧,非常具有实用价值,需要的朋友可以参考下
本文实例讲述了C++实现邮件群发的方法。分享给大家供大家参考。具体如下:
关于生成随机QQ邮箱不精确的问题,在之后版本打算另写一个采集器插件进行帐号采集,所以,这个软件只用来进行内容发送,邮箱进行随机生成
如果你已经有采集来的QQ号,请复制到SendList.txt 替换内容即可
可以直接复制HTML代码到邮件内容,保存即可。目前邮件内容最大设置为10000字节,如果有增大的必要,欢迎提交留言。
这是我学习后VC编程中涉及到多线程,socket,及一些WINDOWSAPI的宗合应用
使用说明:
一、SMTP设置
1、SMTP设置中,收件箱地址:填写邮箱地址为帐号测试邮箱,可以填写你自己的邮箱作为接收测试。打星号为必填。邮箱帐号及密码,是即将用于群发的帐号和密码
2、群发发送时间间隔,默认为零,可以选择填写发送间隔时间,单位为秒,防止多次快速发送相同内容被停用。
3、勾选邮件标题后插入系统时间,可以在标题上加上系统时间
4、导入群发列表,勾选后,可以点击群发,暂停,继续。(群发列表为程序目录中SendList.txt)如果你有邮箱采集软件,可以把彩集的邮箱地址按照格式,一行一个,放入其中),没有的话,可以点击“收件箱”页面生成随机QQ邮箱
二、邮件内容
1、填写邮件标题,邮件内容可以为纯文本,也可以是HTML代码,附件目前只支持TXT文本。
2、群发前,请测试邮件内容,是否完整。附件是否正常接收。
三、收件箱
1、收件箱中顺序生成QQ邮箱,请不要超过6位数QQ号,位数过大,生成时间过长,容易造成假死。
2、群发前,先生成QQ邮箱列表。如果你有采集邮箱帐号,可以按格式放入SendList.txt 中
版本更新说明:
1、可增加多个附件。
2、修复标题插入日期造成程序崩溃的BUG。
3、增加发送间隔时间选项。
4、支持HTML代码
5、增加干预码
#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>
#include "Resource.h"
#include "TabDlg1.h"
#include "winsock2.h"
#define MAXSTRING 10000
static int flag=; //标记是否群发
TCHAR* pTitle = NULL; //指向标题文件内容的指针
HANDLE hThread=NULL; //线程返回句柄
long i=; //列表控件“行”计数
static long sendNum=; //发送邮件数量
#pragma comment(lib,"WSOCK32.LIB")
extern TCHAR tcRunPath[MAX_PATH]; //程序当前路径目录
extern TCHAR shortPath[MAX_PATH]; //文件路径,TAB2中的全局变量
extern TCHAR titlePath[]; //邮件标题文件路径
extern TCHAR mtPath[]; //邮件内容文件路径
extern TCHAR sendListPath[MAX_PATH]; //发送列表文件路径
extern BOOL attach; //是否添加了附件
extern TCHAR file[MAXSTRING]; //附件部份代码
BOOL WINAPI TAB1_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
HANDLE_MSG(hWnd, WM_INITDIALOG, TAB1_OnInitDialog);
HANDLE_MSG(hWnd, WM_COMMAND, TAB1_OnCommand);
HANDLE_MSG(hWnd,WM_CLOSE, TAB1_OnClose);
}
return FALSE;
}
BOOL TAB1_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
InitLVColumn(hwnd);
InitComboBox(hwnd);
return TRUE;
}
void TAB1_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
IsChecked(hwnd); //判断勾选框是否被勾选
IsRadioChecked(hwnd); //RADIO控件是否被选择
switch(id)
{
case IDC_MAIL_TEST:
{
if(IsDlgButtonChecked(hwnd,IDC_RADIO_QQ)!=BST_CHECKED && IsDlgButtonChecked(hwnd,IDC_RADIO_163)!=BST_CHECKED)
{
MessageBox(hwnd,TEXT("请选择发QQ邮箱或163信箱"),"",MB_OK);
return;
}
else
{
flag=;
hThread=CreateThread(NULL,,ThreadFunc,hwnd,,);
}
}
break;
case IDC_BUTTON_START:
{
if(IsDlgButtonChecked(hwnd,IDC_RADIO_QQ)!=BST_CHECKED && IsDlgButtonChecked(hwnd,IDC_RADIO_163)!=BST_CHECKED)
{
MessageBox(hwnd,TEXT("请选择发QQ邮箱或163信箱"),"",MB_OK);
return;
}
else
{
flag=;
hThread=CreateThread(NULL,,ThreadFunc,hwnd,,);
}
}
break;
case IDC_BUTTON_PAUSE:
{
if(NULL!=hThread)
{
SuspendThread(hThread);
}
else
{
return;
}
}
break;
case IDC_BUTTON_RESUME:
{
if(NULL!=hThread)
{
ResumeThread(hThread);
}
else
{
return;
}
}
break;
default:
break;
}
}
void TAB1_OnClose(HWND hwnd)
{
EndDialog(hwnd, );
}
int InitLVColumn(HWND hwnd) //列表初始化设置,视图选为报表视图
{
LVCOLUMN lvColumn;
MyLVColumn MyColumn[] = {{TEXT("编号"), 0x30, LVCFMT_CENTER},{TEXT("邮箱帐号"), 0x99, LVCFMT_CENTER}};
lvColumn.mask = LVCF_TEXT|LVCF_FMT|LVCF_WIDTH|LVCF_SUBITEM;
DWORD dwStyle =ListView_GetExtendedListViewStyle(GetDlgItem(hwnd, IDC_LIST)); //得到列表当前拓展风格
dwStyle |= LVS_EX_FULLROWSELECT; //选中某行使整行高亮(只适用与report风格的listctrl)
dwStyle |= LVS_EX_GRIDLINES; //网格线(只适用与report风格的listctrl)
// dwStyle |= LVS_EX_CHECKBOXES; //item前生成checkbox控件
ListView_SetExtendedListViewStyle(GetDlgItem(hwnd, IDC_LIST),dwStyle); //设置列表扩展风格
for(int i = ; i < ; i++)
{
lvColumn.pszText = MyColumn[i].szColumnName;
lvColumn.cx = MyColumn[i].cx;
lvColumn.fmt = MyColumn[i].fmt;
SendDlgItemMessage(hwnd, IDC_LIST, LVM_INSERTCOLUMN, i, (LPARAM)&lvColumn);
} return ;
}
int InitComboBox(HWND hwnd)//窗口控件初始化设置
{
HWND hwndCombo=GetDlgItem(hwnd,IDC_COMBO_SLEEPTIME);
ComboBox_InsertString(hwndCombo,-,TEXT(""));
ComboBox_InsertString(hwndCombo,-,TEXT(""));
ComboBox_InsertString(hwndCombo,-,TEXT(""));
ComboBox_InsertString(hwndCombo,-,TEXT(""));
ComboBox_InsertString(hwndCombo,-,TEXT(""));
ComboBox_InsertString(hwndCombo,-,TEXT(""));
ComboBox_SetText(hwndCombo,TEXT(""));
SetDlgItemText(hwnd,IDC_EDIT_MAILADD,TEXT("12345678@qq.com"));
ComboBox_InsertString(GetDlgItem(hwnd,IDC_COMBO_SMTP),,TEXT("smtp.qq.com"));
ComboBox_InsertString(GetDlgItem(hwnd,IDC_COMBO_SMTP),,TEXT("smtp.163.com"));
ComboBox_SetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),TEXT("smtp.qq.com"));
SetDlgItemText(hwnd,IDC_EDIT_MAILPORT,TEXT(""));
SetDlgItemText(hwnd,IDC_EDIT_USERNAME,TEXT("")); return ;
}
int IsChecked(HWND hwnd) //checkbox未选中的设置为只读
{
if(IsDlgButtonChecked(hwnd,IDC_CHECK_QUNFA)!=BST_CHECKED)
{
EnableWindow(GetDlgItem(hwnd, IDC_BUTTON_START), false);
EnableWindow(GetDlgItem(hwnd, IDC_BUTTON_RESUME), false);
EnableWindow(GetDlgItem(hwnd, IDC_BUTTON_PAUSE), false);
return ;
}
else
{
EnableWindow(GetDlgItem(hwnd, IDC_BUTTON_START), true);
EnableWindow(GetDlgItem(hwnd, IDC_BUTTON_RESUME), true);
EnableWindow(GetDlgItem(hwnd, IDC_BUTTON_PAUSE), true);
return ;
}
return ;
}
int IsRadioChecked(HWND hwnd) //RADIO控件被选中,则设置相应的SMTP 地址
{
if(IsDlgButtonChecked(hwnd,IDC_RADIO_QQ)==BST_CHECKED)
{
ComboBox_SetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),TEXT("smtp.qq.com"));
return ;
}
if(IsDlgButtonChecked(hwnd,IDC_RADIO_163)==BST_CHECKED)
{
ComboBox_SetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),TEXT("smtp.163.com"));
return ;
}
return ;
}
TCHAR* readText1(HWND hwnd) //读取文件--邮件发送内容
{
int nLen = ;
FILE *pF = fopen(titlePath , "r"); //打开文件
fseek(pF, , SEEK_END); //文件指针移到文件尾
nLen = ftell(pF); //得到当前指针位置, 即是文件的长度
rewind(pF); //文件指针恢复到文件头位置
pTitle = (char*) malloc(sizeof(char)*nLen+);//动态申请空间, 为保存字符串结尾标志\0, 多申请一个字符的空间
if(!pTitle)
{
MessageBox(hwnd,TEXT("内存不够!"),"错误",MB_ICONWARNING);
exit();
}
nLen = fread(pTitle, sizeof(char), nLen, pF);
pTitle[nLen] = '\0'; //添加字符串结尾标志
if(IsDlgButtonChecked(hwnd,IDC_CHECK_TITLE)==BST_CHECKED) //是否勾选在邮件标题 加入系统当前时间
{
SYSTEMTIME stLocal;
GetLocalTime(&stLocal); //得到系统当前时间
TCHAR strTime[];
ZeroMemory(strTime,sizeof(strTime)/sizeof(TCHAR));
wsprintf(strTime,"%04u-%02u-%02u %02u:%02u:%02u",stLocal.wYear,stLocal.wMonth,stLocal.wDay,stLocal.wHour,stLocal.wMinute,stLocal.wSecond);
strcat(pTitle,strTime); //在标题后加入系统时间
}
fclose(pF); //关闭文件
TCHAR* pText = NULL;
pF = fopen(mtPath , "r"); //打开文件
fseek(pF, , SEEK_END);
nLen = ftell(pF);
rewind(pF);
pText = (char*) malloc(sizeof(char)*nLen+); //动态申请空间, 为保存字符串结尾标志\0, 多申请一个字符的空间
if(!pText)
{
MessageBox(hwnd,TEXT("内存不够!"),"错误",MB_ICONWARNING);
exit();
}
nLen = fread(pText, sizeof(char), nLen, pF);
pText[nLen] = '\0'; //添加字符串结尾标志
fclose(pF); //关闭文件
TCHAR chText[MAXSTRING];
TCHAR* encText=base64_encode(pText,strlen(pText));
strcpy(chText,encText); //BASE64加密结果
free(encText); //释放指针
free(pText); //释放空间
return chText;
}
DWORD WINAPI ThreadFunc(LPVOID lpParam)//发邮件线程
{
HWND hwnd=(HWND)lpParam;
TCHAR userName[]; //用户帐号
TCHAR userPassWord[]; //用户密码
GetDlgItemText(hwnd,IDC_EDIT_USERNAME,userName,sizeof(userName)/sizeof(TCHAR));
GetDlgItemText(hwnd,IDC_EDIT_USERPASSWORD,userPassWord,sizeof(userPassWord)/sizeof(TCHAR));
TCHAR *name=userName;
int i = ;
int j = strlen(name);
TCHAR *encName = base64_encode(name, j); //给用户名base64加密编码
ZeroMemory(userName,sizeof(userName)/sizeof(TCHAR));
wsprintf(userName,"%s\n", encName); //在加编码后加入回车符
TCHAR *passWord=userPassWord;
int k = strlen(passWord);
TCHAR *encPassWord = base64_encode(passWord, k); //给用户密码base64加密编码
// int len = strlen(enc);
// TCHAR *dec = base64_decode(enc, len); //反编
ZeroMemory(userPassWord,sizeof(userPassWord)/sizeof(TCHAR));
wsprintf(userPassWord,"%s\n", encPassWord);
/*ZeroMemory(userName,sizeof(userName)/sizeof(TCHAR));
wsprintf(userName,"\ndecoded : %s", dec);
MessageBox(hwnd,userName,"",MB_OK);*/ //反编译用户名,如果需要,可以把用户名密码反编后发到指定邮箱。
free(encName); //释放指针
free(encPassWord);
//free(dec);
if(==flag) //全局标记,点击群发还是测试,1为群发,0为测试
{
HANDLE wFile;
int szId;
TCHAR ch;
TCHAR szState[];
strcpy(sendListPath,tcRunPath);
strcat(sendListPath,"\\SendList.txt"); //拼接全路径及文件名
TCHAR *sFileName=sendListPath;
FILE *fp=fopen(sFileName,"r");
if(fp==NULL)
{
return FALSE; //打开文件失败,则返回,不读取
}
fseek(fp, , SEEK_END);
int length = ftell(fp); //length为0,则是空的
rewind(fp); //把指针移回文件头部 还可以用 fseek(fp, 0, SEEK_SET);效果一样
if(length==) //判断文件如果为空,则关闭文件,返回,
{
fclose(fp); //要关闭打开的文件,不然退出时,无法保存
return FALSE;
}
while(!feof(fp))
{
fscanf(fp,"%s\r\n",szState);
SocketQ(hwnd,userName,userPassWord,szState);
TCHAR sTime[];
unsigned long iTime;
ComboBox_GetText(GetDlgItem(hwnd,IDC_COMBO_SLEEPTIME),sTime,sizeof(sTime)/sizeof(TCHAR));
iTime=atoi(sTime);
iTime=iTime*;
Sleep(iTime);
}
fclose(fp);
}
else
{
Socket(hwnd,userName,userPassWord);
}
CloseHandle(hThread);
return ;
}
void SocketQ(HWND hwnd,TCHAR userName[],TCHAR userPassWord[],TCHAR szState[])//传入加密的用户名跟密码连接163
{
/*******************************************************************
使用Socket的程序在使用Socket之前必须调用WSAStartup函数。
该函数的第一个参数指明程序请求使用的Socket版本,
其中高位字节指明副版本、低位字节指明主版本;
操作系统利用第二个参数返回请求的Socket的版本信息。
当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,
然后绑定找到的Socket库到该应用程序中。
以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。
该函数执行成功后返回0。
*****************************************************************/
TCHAR* pText;
pText = readText1(hwnd);
int WSA_return;
WSADATA wsaData;
WSA_return=WSAStartup(MAKEWORD(,),&wsaData); //初始化Socket库
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建SOCKET
hostent* host = NULL;
SOCKADDR_IN sa;
sa.sin_family=AF_INET; //设置电线连接服务器端的端口
TCHAR cPort[];
GetDlgItemText(hwnd,IDC_EDIT_MAILPORT,cPort,sizeof(cPort)/sizeof(TCHAR));
int iPort=atoi(cPort);
sa.sin_port = htons(iPort);
//sa.sin_addr.S_un.S_addr = inet_addr("123.58.178.203");//可以写死IP地址
HOSTENT *host_entry; //存放主机域名,如smtp.qq.com
TCHAR host_name[]="";
ZeroMemory(host_name,sizeof(host_name)/sizeof(TCHAR));
ComboBox_GetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),host_name,sizeof(host_name)/sizeof(TCHAR));
TCHAR str_ipAdd[];
if(WSA_return==)
{
host_entry=gethostbyname(host_name); // 要解析的域名或主机名
if(host_entry!=NULL)
{
wsprintf(str_ipAdd,"%d.%d.%d.%d",
(host_entry->h_addr_list[][]&0x00ff),
(host_entry->h_addr_list[][]&0x00ff),
(host_entry->h_addr_list[][]&0x00ff),
(host_entry->h_addr_list[][]&0x00ff)); }
}
sa.sin_addr.S_un.S_addr = inet_addr(str_ipAdd); //得到域名IP地址
if(connect(sock,(SOCKADDR *)&sa,sizeof(sa))==SOCKET_ERROR)
{
ShowError();
return;
}
TCHAR buffer[]; //对话过程
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
int iRet=recv(sock,buffer,,); //接收问候语
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
TCHAR Hello[] = "HELO SMTP\r\n"; //注意不能忘了末尾的回车
send(sock,Hello,lstrlen(Hello),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
TCHAR Ehlo[] = "EHLO SMTP\r\n";
send(sock,Ehlo,lstrlen(Ehlo),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
TCHAR login[] = "AUTH LOGIN\r\n"; //登陆命令
send(sock,login,lstrlen(login),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
if(IsDlgButtonChecked(hwnd,IDC_RADIO_QQ)==BST_CHECKED)
{
strcat(userName,"\r\n");
send(sock,userName,lstrlen(userName),); //发送加密的用户名
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
strcat(userPassWord,"\r\n");
send(sock,userPassWord,lstrlen(userPassWord),); //发送加密的密码
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
}
if(IsDlgButtonChecked(hwnd,IDC_RADIO_163)==BST_CHECKED)
{
send(sock,userName,lstrlen(userName),); //发送加密的用户名
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
send(sock,userPassWord,lstrlen(userPassWord),); //发送加密的密码
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
}
TCHAR userF[];
TCHAR userL[];
TCHAR temp[];
GetDlgItemText(hwnd,IDC_EDIT_USERNAME,userF,sizeof(userF)/sizeof(TCHAR));
ComboBox_GetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),temp,sizeof(host_name)/sizeof(TCHAR));
strcat(userF,"@");
strncpy(userL,temp+,sizeof(userL));
strcat(userF,userL);
TCHAR mailFrom[];
//MessageBox(hwnd,userF,"",MB_OK);
wsprintf(mailFrom,TEXT("MAIL FROM:<%s>\r\n"),userF);
send(sock,mailFrom,lstrlen(mailFrom),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
TCHAR mailTo[];
wsprintf(mailTo,TEXT("RCPT TO:<%s>\r\n"),szState);
send(sock,mailTo,lstrlen(mailTo),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
TCHAR dataCommad[]="DATA\r\n";
send(sock,dataCommad,lstrlen(dataCommad),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
//下面是发送正文及附件部份
TCHAR data[];
TCHAR SetMailHead[]; //邮件头部信息
wsprintf(SetMailHead,TEXT("To:%s\r\nFrom:%s\r\nSubject: %s\r\n"
"Date:2012-8-24\r\nX-Mailer:Kevin's mailer\r\nMIME-Version:1.0\r\n"
"Content-Type: multipart/mixed;\r\n"
" boundary=\"----=_NextPart_5039E410_D41071F0_120ABDFB\";\r\n"
"This is a multi-part message in MIME format.\r\n\r\n"
"------=_NextPart_5039E410_D41071F0_120ABDFB\r\n"
"Content-Type: multipart/alternative;\r\n"
" boundary=\"----=_NextPart_5039E410_D41071F0_53510C95\";\r\n\r\n"
"------=_NextPart_5039E410_D41071F0_53510C95\r\n"
"Content-Type: text/plain;\r charset=\"gb2312\"\r\n"
"Content-Transfer-Encoding: base64\r\n\r\n"),szState,userF,pTitle);
strcat(SetMailHead,pText); //邮件头部再加上正文文本内容
strcat(SetMailHead,TEXT("\r\n\r\n"));
strcpy(data,SetMailHead);
TCHAR SetMailHtml[]; //邮件HTML代码部份
wsprintf(SetMailHtml,TEXT("------=_NextPart_5039E410_D41071F0_53510C95\r\n"
"Content-Type: text/html;\r\n"
" charset=\"gb2312\"\r\n"
"Content-Transfer-Encoding: base64\r\n\r\n"));
strcat(SetMailHtml,pText); //加入邮件内容
strcat(SetMailHtml,TEXT("\r\n\r\n------=_NextPart_5039E410_D41071F0_53510C95--\r\n\r\n"));
strcat(data,SetMailHtml);
if(TRUE==attach) //判断是否添加了附件路径
{
strcat(data,file); //加入附件部份代码
strcat(data,TEXT("------=_NextPart_5039E410_D41071F0_120ABDFB--\r\n"));
}
send(sock,data,lstrlen(data),);
TCHAR cN[]="\r\n.\r\n"; //邮件结束标志
send(sock,cN,lstrlen(cN),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
TCHAR cQuit[] = "QUIT\r\n"; //退出命令
send(sock,cQuit,lstrlen(cQuit),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
TCHAR cNum[];
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
else
{
TCHAR str[]; //输出已发送列表
wsprintf(str,"%i",sendNum);
LVITEM lvItem;
lvItem.mask = LVIF_TEXT;
lvItem.iSubItem = ;
int ItemCount = ListView_GetItemCount(GetDlgItem(hwnd, IDC_LIST));
lvItem.iItem = ItemCount;
lvItem.pszText = str;
SendDlgItemMessage(hwnd, IDC_LIST, LVM_INSERTITEM, , (LPARAM)&lvItem);
ListView_SetItemText(GetDlgItem(hwnd, IDC_LIST), i++, , szState);
sendNum++;
}
free(pTitle); //释放空间
closesocket(sock); //关闭SOCKET
WSACleanup();
return;
}
void Socket(HWND hwnd,TCHAR userName[],TCHAR userPassWord[])//传入加密的用户名跟密码连接163
{
TCHAR* pText;
pText = readText1(hwnd);
int WSA_return;
WSADATA wsaData;
WSA_return=WSAStartup(MAKEWORD(,),&wsaData);//初始化Socket库
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
hostent* host = NULL;
SOCKADDR_IN sa;
sa.sin_family=AF_INET; //设置电线连接服务器端的端口
TCHAR cPort[];
GetDlgItemText(hwnd,IDC_EDIT_MAILPORT,cPort,sizeof(cPort)/sizeof(TCHAR));
int iPort=atoi(cPort);
sa.sin_port = htons(iPort);
HOSTENT *host_entry;
TCHAR host_name[]="";
ZeroMemory(host_name,sizeof(host_name)/sizeof(TCHAR));
ComboBox_GetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),host_name,sizeof(host_name)/sizeof(TCHAR));
TCHAR str_ipAdd[];
if(WSA_return==)
{
host_entry=gethostbyname(host_name); // 即要解析的域名或主机名
if(host_entry!=NULL)
{
wsprintf(str_ipAdd,"%d.%d.%d.%d",
(host_entry->h_addr_list[][]&0x00ff),
(host_entry->h_addr_list[][]&0x00ff),
(host_entry->h_addr_list[][]&0x00ff),
(host_entry->h_addr_list[][]&0x00ff)); }
}
sa.sin_addr.S_un.S_addr = inet_addr(str_ipAdd);
if(connect(sock,(SOCKADDR *)&sa,sizeof(sa))==SOCKET_ERROR)
{
ShowError();
return;
}
TCHAR buffer[]; //对话过程
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
int iRet=recv(sock,buffer,,); //接收问候语
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
TCHAR Hello[] = "HELO SMTP\r\n"; //注意不能忘了末尾的回车
send(sock,Hello,lstrlen(Hello),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
TCHAR Ehlo[] = "EHLO SMTP\r\n";
send(sock,Ehlo,lstrlen(Ehlo),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
TCHAR login[] = "AUTH LOGIN\r\n"; //登陆命令
send(sock,login,lstrlen(login),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
if(IsDlgButtonChecked(hwnd,IDC_RADIO_QQ)==BST_CHECKED)
{
strcat(userName,"\r\n");
send(sock,userName,lstrlen(userName),); //发送加密的用户名
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
strcat(userPassWord,"\r\n");
send(sock,userPassWord,lstrlen(userPassWord),); //发送加密的密码
// 何问起 hovertree.com
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
}
if(IsDlgButtonChecked(hwnd,IDC_RADIO_163)==BST_CHECKED)
{
send(sock,userName,lstrlen(userName),); //发送加密的用户名
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
send(sock,userPassWord,lstrlen(userPassWord),); //发送加密的密码
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
}
TCHAR userF[];
TCHAR userL[];
TCHAR temp[];
GetDlgItemText(hwnd,IDC_EDIT_USERNAME,userF,sizeof(userF)/sizeof(TCHAR));
ComboBox_GetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),temp,sizeof(host_name)/sizeof(TCHAR));
strcat(userF,"@");
strncpy(userL,temp+,sizeof(userL));
strcat(userF,userL);
TCHAR mailFrom[];
//MessageBox(hwnd,userF,"",MB_OK);
wsprintf(mailFrom,TEXT("MAIL FROM:<%s>\r\n"),userF);
send(sock,mailFrom,lstrlen(mailFrom),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
TCHAR mailAdd[];
GetDlgItemText(hwnd,IDC_EDIT_MAILADD,mailAdd,sizeof(mailAdd)/sizeof(TCHAR));
TCHAR mailTo[];
wsprintf(mailTo,TEXT("RCPT TO:<%s>\r\n"),mailAdd);
send(sock,mailTo,lstrlen(mailTo),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
TCHAR dataCommad[]="DATA\r\n";
send(sock,dataCommad,lstrlen(dataCommad),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
//下面是发送正文及附件部份
TCHAR data[];
TCHAR SetMailHead[]; //邮件头部信息
wsprintf(SetMailHead,TEXT("To:%s\r\nFrom:%s\r\nSubject: %s\r\n"
"Date:2012-8-24\r\nX-Mailer:Kevin's mailer\r\nMIME-Version:1.0\r\n"
"Content-Type: multipart/mixed;\r\n"
" boundary=\"----=_NextPart_5039E410_D41071F0_120ABDFB\";\r\n"
"This is a multi-part message in MIME format.\r\n\r\n"
"------=_NextPart_5039E410_D41071F0_120ABDFB\r\n"
"Content-Type: multipart/alternative;\r\n"
" boundary=\"----=_NextPart_5039E410_D41071F0_53510C95\";\r\n\r\n"
"------=_NextPart_5039E410_D41071F0_53510C95\r\n"
"Content-Type: text/plain;\r charset=\"gb2312\"\r\n"
"Content-Transfer-Encoding: base64\r\n\r\n"),mailAdd,userF,pTitle);
strcat(SetMailHead,pText); //邮件头部再加上正文文本内容
strcat(SetMailHead,TEXT("\r\n\r\n"));
strcpy(data,SetMailHead);
TCHAR SetMailHtml[]; //邮件HTML代码部份
wsprintf(SetMailHtml,TEXT("------=_NextPart_5039E410_D41071F0_53510C95\r\n"
"Content-Type: text/html;\r\n"
" charset=\"gb2312\"\r\n"
"Content-Transfer-Encoding: base64\r\n\r\n"));
strcat(SetMailHtml,pText); //加入邮件内容
strcat(SetMailHtml,TEXT("\r\n\r\n------=_NextPart_5039E410_D41071F0_53510C95--\r\n\r\n"));
strcat(data,SetMailHtml);
if(TRUE==attach) //判断是否添加了附件路径
{
strcat(data,file); //加入附件部份代码
strcat(data,TEXT("------=_NextPart_5039E410_D41071F0_120ABDFB--\r\n"));
}
send(sock,data,lstrlen(data),);
TCHAR cN[]="\r\n.\r\n"; //邮件结束标志
send(sock,cN,lstrlen(cN),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
TCHAR cQuit[] = "QUIT\r\n"; //退出命令
send(sock,cQuit,lstrlen(cQuit),);
ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));
iRet=recv(sock,buffer,,);
TCHAR cNum[];
if(SOCKET_ERROR==iRet)
{
ShowError();
return;
}
else
{
MessageBox(hwnd,TEXT("测试发送成功"),TEXT("恭喜"),MB_OK);
}
free(pTitle); //释放空间
closesocket(sock); //关闭SOCK
WSACleanup();
return;
}
void ShowError()
{
TCHAR* lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER| //自动分配消息缓冲区
FORMAT_MESSAGE_FROM_SYSTEM, //从系统获取信息
NULL,GetLastError(), //获取错误信息标识
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), //使用系统缺省语言
(LPTSTR)&lpMsgBuf, //消息缓冲区
,
NULL);
MessageBox(NULL,lpMsgBuf,"",MB_ICONERROR);
}
hovertree
希望本文所述对大家的C++程序设计有所帮助。
推荐:http://www.cnblogs.com/roucheng/p/cppjy.html
C++实现邮件群发的方法的更多相关文章
- 通什翡翠商城大站协议邮件群发系统日发20-30万封不打码不换ip不需发件箱100%进收件箱
用一种新的技术思维去群发邮件一种不用换IP,不需要任何发件箱的邮件群发方式一种不需要验证码,不需要**代码变量的邮件群发方式即使需要验证码也能全自动识别验证码的超级智能软件教你最核心的邮件群发思维和软 ...
- 懒人邮件群发日发50-100万封不打码不换IP不需发件箱大站协议系统营销软件100%进收件箱
用一种新的技术思维去群发邮件 一种不用换IP,不需要任何发件箱的邮件群发方式 一种不需要验证码,不需要**代码变量的邮件群发方式 即使需要验证码也能全自动识别验证码的超级智能软件 教你最核心的邮件群发 ...
- EDM邮件群发十大技巧提升邮件群发效果
有很多人抱怨现在邮件群发没有什么效果,其实不然,每一种推广方式都有他的优势,没有看到效果说明你没有掌握好方法.个人觉得EDM邮件群发的优势在于传播速度快.不受地域限制.不受时间限制.邮件内容能够多元化 ...
- 各大免费邮箱邮件群发账户SMTP服务器配置及SMTP发送量限制情况
网络产品推广和新闻消息推送时,经常用到的工具就是用客户邮箱发送邮件了,如果是要发送的邮件量非常大的话,一般的建议是搭建自己的邮局服务器,或者是花钱购买专业的邮件群发服务,免费邮箱的SMTP适合少量的邮 ...
- 5分钟 wamp下php phpmaile发送qq邮件 2015最新方法说明
13:40 2015/11/20 5分钟 wamp下php phpmaile发送qq邮件 2015最新方法说明 关键点:现在qq邮箱开通smtp服务后会给你一个很长的独立新密码,发邮件配置中的密码需要 ...
- U-Mail邮件群发触发器功能助力营销自动化
小编在朋友圈看到的人工智能讨论越来越多,越来越多的上班族惶恐不安,担心自己的饭碗不保将被人工智能所取代,这说明智能化.自动化正成为各行业的趋势,营销也概莫能外.营销的自动化意味着将大大节省从业人员的精 ...
- U-Mail邮件群发:邮件营销最全建议
U-Mail专注于邮件营销平台研发工作多年了,服务企业数千家,拥有上万IP,在国内外基础设施建设上投资巨大,技术团队精湛.客服人员热情,赢 得了业界的好评和用户信任.有一些用户给我们发来邮件或来电咨询 ...
- U-Mail邮件群发如何过滤无效地址?
U-Mail邮件群发平台可以自动过滤掉无效和重复地址,过滤效果如下图 U-Mail邮件群发平台会将客户已经确认好是无效地址的加入无效地址库,下次再导入改无效地址就直接拒绝.邮件格式不正确的也会直接过滤 ...
- EDM邮件群发:群发邮件不进垃圾箱的独家秘笈
EDM邮件群发想要群发的邮件避免进入垃圾箱,不仅需要优化邮件内容和主题,管理收件人邮箱列表,还要有多服务器IP分流技术,控制发信速度,打乱收件人列表等手段,当然更少不了借助专业的邮件群发平台譬如U-M ...
随机推荐
- .NET面试题系列[13] - LINQ to Object
.NET面试题系列目录 名言警句 "C# 3.0所有特性的提出都是更好地为LINQ服务的" - Learning Hard LINQ是Language Integrated Que ...
- 企业IT管理员IE11升级指南【5】—— 不跟踪(DNT)例外
企业IT管理员IE11升级指南 系列: [1]—— Internet Explorer 11增强保护模式 (EPM) 介绍 [2]—— Internet Explorer 11 对Adobe Flas ...
- eclipse启动时报告错误:Java was started but returned exit code=-805306369
这两天也没改过eclipse和java的配置,但eclipse启动时报告错误:Java was started but returned exit code=-805306369 后来在eclipse ...
- 《Entity Framework 6 Recipes》中文翻译系列 (44) ------ 第八章 POCO之POCO中使用值对象和对象变更通知
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 8-4 POCO中使用值对象(Complex Type--也叫复合类型)属性 问题 ...
- 安装Oracle 12c精简客户端(不带数据库)
注:Oracle客户端向下兼容,故也可以连接11g的数据库 下载页面皆为:http://www.oracle.com/technetwork/topics/winsoft-085727.html ...
- sql的行转列(PIVOT)与列转行(UNPIVOT)
在做数据统计的时候,行转列,列转行是经常碰到的问题.case when方式太麻烦了,而且可扩展性不强,可以使用 PIVOT,UNPIVOT比较快速实现行转列,列转行,而且可扩展性强 一.行转列 1.测 ...
- 【WP开发】加密篇:单向加密
单向加密,简单地说就是对数据进行哈希处理,平时我们见得较多的有MD5.SHA1等,都属于单向加密.上一篇文章中,老周跟大家扯了有关双向加密的事,本文咱们就扯一下单向加密吧. 要对数据进行哈希处理也不是 ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 用户部分(1)用户注册
上一次把基本框架搭建起来了,这次开始整Web部分,终于可以看到界面了小激动一下.web项目部分从用户功能开始,基本有注册,登录.注销.查找.查看.删除等涉及Member区域和Manage区域. 目录: ...
- MongoDB学习系列(2)--使用PHP访问MongoDB
第一部分:介绍 在Windows上安装最新MongoDB步骤非常的简单,这里不做介绍.但是如果你安装的时候没有将MongoDB作为服务运行,每次你都要使用cmd切换到指定的目录下,然后在cmd中启动M ...
- 基础知识javascript--事件
群里有一个小伙伴在处理事件监听函数的时候,遇到了一点问题,正好我比较空闲,于是帮他指出了代码中的问题,顺便整理一下,方便以后遇到类似问题的伙伴们有一个参考. 这是一个很简单的问题,对于基础知识比较杂实 ...