用CBrother脚本实现smtp协议发送一份邮件
用CBrother脚本实现smtp协议发送一份邮件
之前用CBrother脚本写了一个拯救“小霸王服务器”的程序,公司人用着都挺好用,但是有时候谁重启了服务器其他人不知道,造成了多人多次重启,每个人都抢救一遍,大家一再要求我添加功能,有一个人重启后给其他人发一封邮件。
靠,真是“饱暖思淫欲”,之前没有这个重启系统的时候,都得连到服务器上去重启,哎。。。人啊。。。。。
有“”祖传背锅侠“称号的我也只能硬着头皮去做了,于是用CBrother实现了smtp协议,可以发送邮件了
先来看看封装的发邮件EMailSender类的用法:
//EMailSender是我封装的邮件发送类,全局new一个
var mailSender = new EMailSender();
function main()
{
//启动邮件发送
mailSender.start(); //创建一个封邮件 Mail是我封装的一个描述邮件内容的类
var mail = new Mail();
//设置发送者的邮箱 的 名称 地址 密码
mail.setSender("zhangZsan","zhangZsan1122334@163.com","123456789");
//设置收件人 多个收件人就添加多条 SEND_TO表示是接收人
mail.addRecipient("boss","myboss_aaaa123@qq.com",SEND_TO);
mail.addRecipient("erhuo","erhuo_aaaa123@qq.com",SEND_TO);
//设置抄送邮箱 SEND_CC表示抄送
mail.addRecipient("nvshen","nvshen_aaa123@163.com",SEND_CC);
//设置秘密抄送 SEND_BCC表示秘密抄送
mail.addRecipient("erdaye","erdaye_aaa123@qq.com",SEND_BCC);
//设置右键标题
mail.setTitle("服务器被重启了");
//设置右键内容
mail.setValue("服务器被erhuo重启了.");
//发送邮件
mailSender.sendMail(mail); //sendMail调用一次发一封,调用两次发两封 while (1)
{
Sleep(1000);
}
}
使用还是很简单了,对于封装,我是认真的,哈哈。当然,这里面的邮箱地址都是胡写的,你不用去163试密码了。。。。。
再来看看实现代码:
//包含cbrother的socket模块
import CBSocket.code //这些定义是发送邮件的步骤,可以忽略不看
const MAIL_STEP_NORMAL = 0;
const MIAL_STEP_EHLO = 1;
const MAIL_STEP_LOGIN = 2;
const MAIL_STEP_ACCOUNT = 3;
const MAIL_STEP_PWD = 4;
const MAIL_STEP_FROM = 5;
const MAIL_STEP_DATA = 6;
const MAIL_STEP_QUIT = 7;
const MAIL_STEP_OVER = 8; //邮件内容分割线,邮件格式协议里要的,你可以改成自己的
const SPLIC_MAIL = "--_CBROTHER_MAIL_202020202020"; //收件人类型
const SEND_TO = 0; //接收者
const SEND_CC = 1; //抄送
const SEND_BCC = 2; //秘密抄送 //邮件接收者类
class MailUser
{
var Name; //名字
var Addr; //邮箱地址
var Type; //类型
} //描述一封右键
class Mail
{
var _SmtpHost; //smpt服务器地址
var _Sender = new MailUser(); //发送者
var _SendPwd; //发送者密码
var _Recipient = new Array(); //接收者列表
var _MailTitle; //邮件标题
var _MailValue; //邮件内容 //设置发送者信息
function setSender(senderName,senderAddr,senderPwd)
{
var strArr = strsplit(senderAddr,"@");
if (strArr.size() != 2)
{
return false;
} this._SmtpHost = "smtp." + strArr[1];
this._SendPwd = senderPwd; _Sender.Name = senderName;
_Sender.Addr = senderAddr;
return true;
} //添加接收者
function addRecipient(name,addr,type)
{
foreach (k,v : _Recipient)
{
if (v.Addr == addr)
{
v.Name = name;
v.Type = type;
return;
}
} var r = new MailUser();
r.Addr = addr;
r.Name = name;
r.Type = type;
_Recipient.add(r);
} //设置右键标题
function setTitle(title)
{
this._MailTitle = title;
} //设置右键内容
function setValue(value)
{
this._MailValue = value;
}
} //右键发送过程中需要的一些数据
class MailBuf
{
var _mail; //邮件 Mail类对象
var _byteArray = new ByteArray(); //数据缓存
var _step = MAIL_STEP_NORMAL; //右键发送的步骤
var _socketid; //这封优先的socketid
var _recvsendidx = 0; //发送接收者过程中的一个临时变量
} //这个类是邮件发送的smtp协议的主要实现
class EMailSender
{
var _tcpModule = new TcpModule(); //tcp模块
var _Lock = new Lock(); //多线程互斥锁
var _mailMap = new Map(); //存储邮件的map //启动邮件服务
function start()
{
_tcpModule.setTcpAction(this);
_tcpModule.start();
} //发送一封邮件
function sendMail(mail)
{
//连接对方smtp服务器
var socketid = _tcpModule.connect(mail._SmtpHost,25);
print "connect " + mail._SmtpHost + " " +socketid;
if (socketid == 0)
{
print "socketid == 0";
return;
} //连接成功后将socketid和mail绑定,这里多线程有可能OnConnect回调先执行
_Lock.lock();
var mailbuf = _mailMap.get(socketid);
if (mailbuf == null)
{
mailbuf = new MailBuf();
mailbuf._socketid = socketid;
_mailMap.add(socketid,mailbuf);
}
_Lock.unlock(); mailbuf._mail = mail;
} //连接上服务器
function OnConnect(sock)
{
print "onconnect " + sock;
_Lock.lock();
var mailbuf = _mailMap.get(sock);
if (mailbuf == null)
{
mailbuf = new MailBuf();
mailbuf._socketid = socketid;
_mailMap.add(socketid,mailbuf);
}
_Lock.unlock(); if (mailbuf == null)
{
print "OnConnect mail is null";
_tcpModule.closeSocket(sock);
return;
}
} //和服务器连接断开
function OnClose(sock)
{
print "onclose " + sock;
_Lock.lock();
_mailMap.remove(sock);
_Lock.unlock();
} //收到数据
function OnRecv(sock,byteArray,len)
{
_Lock.lock();
var mailbuf = _mailMap.get(sock);
_Lock.unlock(); if (mailbuf == null)
{
print "recv mail is null";
_tcpModule.closeSocket(sock);
return true;
} mailbuf._byteArray.writeBytes(byteArray,len);
print "r:" + mailbuf._byteArray.getReadPos();
print "w:" + mailbuf._byteArray.getWritePos();
MakeMail(mailbuf);
return true;
} //从数据里获取一行,\r\n结束
function GetLine(byteArray)
{
var rpos = byteArray.getReadPos();
var wpos = byteArray.getWritePos(); //print "rpos:" + rpos + " wpos:" + wpos; var res;
for (var i = rpos; i < wpos ; i++)
{
if (byteArray.getByte(i) == '\r')
{
if (i + 1 < wpos)
{
if (byteArray.getByte(i) == '\n')
{
res = byteArray.readString(i - rpos);
byteArray.copy(byteArray,0,i + 2,wpos - i - 2);
byteArray.setReadPos(0);
byteArray.setWritePos(wpos - i - 2);
break;
}
}
else
{
return null;
}
}
else if (byteArray.getByte(i) == '\n')
{
res = byteArray.readString(i - rpos);
byteArray.copy(byteArray,0,i + 1,wpos - i - 1);
byteArray.setReadPos(0);
byteArray.setWritePos(wpos - i - 1);
break;
}
} //print "end rpos:" + byteArray.getReadPos() + " wpos:" + byteArray.getWritePos();
return res;
} //验证服务器返回数据是否正确
function RecvValue(mailbuf,str)
{
var value = GetLine(mailbuf._byteArray);
if (value == null)
{
return 0;
} print value;
//print strlen(value); var len = strlen(str);
var lenvalue = strlen(value);
if (lenvalue < len)
{
return 2;
} var getstr = strget(value,0,len);
if (str != getstr)
{
return 2;
}
return 1;
} //EHLO有特殊性,单数写一个函数
function RecvEHLO(mailbuf,str)
{
while (true)
{
var value = GetLine(mailbuf._byteArray);
if (value == null)
{
return 0;
} print value;
//print strlen(value); var len = strlen(str);
var lenvalue = strlen(value);
if (lenvalue < len)
{
return 2;
} var getstr = strget(value,0,len);
if (str != getstr)
{
return 2;
} if (strget(value,3,4) == " ")
{
return 1;
}
} return 0;
} //这里面主要就是smtp协议部分了,要看懂需要去学习一下
function MakeMail(mailbuf)
{
switch (mailbuf._step)
{
case MAIL_STEP_NORMAL:
{
var res = RecvValue(mailbuf,"220");
if(res == 2)
{
print "MAIL_STEP_NORMAL mail send err!" + mailbuf._mail._SmtpHost;
break;
} if (res == 1)
{
var mailsend = "EHLO " + mailbuf._mail._SmtpHost + "\r\n";
print mailsend;
this._tcpModule.sendData(mailbuf._socketid,mailsend);
mailbuf._step = MIAL_STEP_EHLO;
} break;
}
case MIAL_STEP_EHLO:
{
var res = RecvEHLO(mailbuf,"250");
if(res == 2)
{
print "MIAL_STEP_EHLO mail send err!" + mailbuf._mail._SmtpHost;
break;
} if (res == 1)
{
var mailsend = "AUTH LOGIN\r\n";
print mailsend;
this._tcpModule.sendData(mailbuf._socketid,mailsend);
mailbuf._step = MAIL_STEP_LOGIN;
}
break;
}
case MAIL_STEP_LOGIN:
{
var res = RecvValue(mailbuf,"334");
if(res == 2)
{
print "MAIL_STEP_LOGIN mail send err!" + mailbuf._mail._SmtpHost;
break;
} if (res == 1)
{
var mailsend = base64_encode(mailbuf._mail._Sender.Addr) + "\r\n";
print mailsend;
this._tcpModule.sendData(mailbuf._socketid,mailsend);
mailbuf._step = MAIL_STEP_ACCOUNT;
}
break;
}
case MAIL_STEP_ACCOUNT:
{
var res = RecvValue(mailbuf,"334");
if(res == 2)
{
print "MAIL_STEP_ACCOUNT mail send err!" + mailbuf._mail._SmtpHost;
break;
} if (res == 1)
{
var mailsend = base64_encode(mailbuf._mail._SendPwd) + "\r\n";
print mailsend;
this._tcpModule.sendData(mailbuf._socketid,mailsend);
mailbuf._step = MAIL_STEP_PWD;
}
break;
}
case MAIL_STEP_PWD:
{
var res = RecvValue(mailbuf,"235");
if(res == 2)
{
print "MAIL_STEP_PWD mail send err!" + mailbuf._mail._SmtpHost;
break;
} if (res == 1)
{
var mailsend = "MAIL FROM: <" + mailbuf._mail._Sender.Addr + ">\r\n";
print mailsend;
this._tcpModule.sendData(mailbuf._socketid,mailsend);
mailbuf._step = MAIL_STEP_FROM;
}
break;
}
case MAIL_STEP_FROM:
{
var res = RecvValue(mailbuf,"250");
if(res == 2)
{
print "MAIL_STEP_FROM mail send err!" + mailbuf._mail._SmtpHost;
break;
} if (res == 1)
{
if (mailbuf._recvsendidx < mailbuf._mail._Recipient.size())
{
var mailsend = "RCPT TO: <" + mailbuf._mail._Recipient[mailbuf._recvsendidx++].Addr + ">\r\n";
print mailsend;
this._tcpModule.sendData(mailbuf._socketid,mailsend);
mailbuf._step = MAIL_STEP_FROM;
}
else
{
var mailsend = "DATA\r\n";
print mailsend;
this._tcpModule.sendData(mailbuf._socketid,mailsend);
mailbuf._step = MAIL_STEP_DATA;
}
}
break;
}
case MAIL_STEP_DATA:
{
var res = RecvValue(mailbuf,"354");
if(res == 2)
{
print "MAIL_STEP_DATA mail send err!" + mailbuf._mail._SmtpHost;
break;
} if (res == 1)
{
var mailsend = MakeMailHead(mailbuf);
print mailsend;
this._tcpModule.sendData(mailbuf._socketid,mailsend); mailsend = MakeMailValue(mailbuf);
print mailsend;
this._tcpModule.sendData(mailbuf._socketid,mailsend);
mailbuf._step = MAIL_STEP_QUIT;
}
break;
}
case MAIL_STEP_QUIT:
{
var res = RecvValue(mailbuf,"250");
if(res == 2)
{
print "MAIL_STEP_QUIT mail send err!" + mailbuf._mail._SmtpHost;
break;
} if (res == 1)
{
var mailsend = "QUIT\r\n";
this._tcpModule.sendData(mailbuf._socketid,mailsend);
mailbuf._step = MAIL_STEP_OVER;
} break;
}
case MAIL_STEP_OVER:
{
var res = RecvValue(mailbuf,"221");
if(res == 2)
{
print "MAIL_STEP_OVER mail send err!" + mailbuf._mail._SmtpHost;
break;
} if (res == 1)
{
this._tcpModule.closeSocket(mailbuf._socketid);
print "mail send success:" + mailbuf._mail._SmtpHost;
}
break;
}
default:
{
break;
}
}
} function MimeCode(basestr)
{
return "=?utf-8?b?" + base64_encode(basestr) + "?=";
} function MakeMailHead(mailbuf)
{
var myTime = new Time(time() - 28800);
var head = "Date: " + myTime.strftime("%a, %d %b %Y %H:%M:%S GMT") + "\r\n"; head += "From: \"" + MimeCode(mailbuf._mail._Sender.Name) + "\" <" + mailbuf._mail._Sender.Addr + ">\r\n";
head += "To: "; var ccmsg = "Cc: ";
var ccflag = 0;
var bccmsg = "Bcc: ";
var bccflag = 0;
for (var i = 0; i < mailbuf._mail._Recipient.size() ; i++)
{
var sender = mailbuf._mail._Recipient[i];
if (sender.Type == SEND_TO)
{
if (i != 0)
{
head += ",";
} head += "\"" + MimeCode(sender.Name) + "\" <" + sender.Addr + ">";
}
else if (sender.Type == SEND_CC)
{
if (ccflag++ != 0)
{
ccmsg += ",";
} ccmsg += "\"" + MimeCode(sender.Name) + "\" <" + sender.Addr + ">";
}
else
{
if (bccflag++ != 0)
{
bccmsg += ",";
} bccmsg += "\"" + MimeCode(sender.Name) + "\" <" + sender.Addr + ">";
}
} head += "\r\n"; if (ccmsg != "Cc: ")
{
head += ccmsg + "\r\n";
} if (bccmsg != "Bcc: ")
{
head += bccmsg + "\r\n";
} head += "Subject: " + MimeCode(mailbuf._mail._MailTitle) + "\r\n"; head += "MIME-Version: 1.0\r\n";
head += "Content-type: multipart/mixed; boundary=\"" + SPLIC_MAIL + "\"\r\n";
head += "\r\n"; return head;
} function MakeMailValue(mailbuf)
{
var valuemsg = "--" + SPLIC_MAIL + "\r\n";
valuemsg += "Content-Type: text/html; charset=utf-8\r\n";
valuemsg += "Content-Transfer-Encoding: base64\r\n\r\n";
valuemsg += base64_encode(mailbuf._mail._MailValue) + "\r\n";
valuemsg += "\r\n--" + SPLIC_MAIL + "--\r\n" + ".\r\n";
return valuemsg;
}
}
我自认为封装的还是比较简单的,当然如果你要用这个代码发邮件,那么你自己的邮箱必须开启smtp授权
,如何开启,不同厂商提供的邮箱方式都不一样,一般都是登录到邮箱里设置一个东西具体你可以百度一下自己的邮箱,比如搜索:163邮箱如何开启smtp,qq邮箱如何开启smtp等。
当运行了以后,接收方就收到了
如果给手机上装上邮箱APP,允许后台推送,手机也会收到提醒,这可能是成本最低的实时通知到手机上的方式了吧。
用CBrother脚本实现smtp协议发送一份邮件的更多相关文章
- C#使用SMTP协议发送验证码到QQ邮箱
C#使用SMTP协议发送验证码到QQ邮箱 在程序设计中,发送验证码是常见的一个功能,用户在注册账号时或忘记密码后,通常需要发送验证码到手机短信或邮箱来验证身份,此篇博客介绍在C#中如何使用SMTP协议 ...
- C# WinForm 使用SMTP协议发送QQ邮箱验证码
文章来自:https://blog.csdn.net/IT_xiao_guang_guang/article/details/104336604 前言 在程序设计中,发送验证码是常见的一个功能,用 ...
- PHP+socket+SMTP、POP3协议发送、接收邮件
.实现SMTP协议的类dsmtp.cls.php:<?php , $webname=).); } } .实现POP3协议的类dpop3.cls.php: <? ...
- python3:利用SMTP协议发送QQ邮件+附件
转载请表明出处:https://www.cnblogs.com/shapeL/p/9115887.html 1.发送QQ邮件,首先必须知道QQ邮箱的SMTP服务器 http://service.mai ...
- SMTP协议解读以及如何使用SMTP协议发送电子邮件
电子邮件协议中POP3协议用于接收邮件,SMTP协议用于发送邮件.SMTP的全称为Simple Mail Transfer Protocol,也就是简单邮件传输协议,字如其名. 相较于POP3而言 ...
- 基于SMTP协议的CMD命令邮件发送
网上有不少的这类的文章,以是参照这些文章后,自己实际运行的结果.系统使用的是WIN7 旗舰版. 1.打开CMD命令后,连接到SMTP服务器,如连接到QQ的SMTP服务,输入命令 telnet smtp ...
- python3之模块SMTP协议客户端与email邮件MIME对象
转载自https://www.cnblogs.com/zhangxinqi/p/9113859.html 阅读目录 1.smtplib模块的常用类与方法 2.处理邮件MIME 3.实例 (1)使用HT ...
- JavaMail使用SMTP协议发送电子邮件(详解)
Properties props = new Properties(); props.setProperty("mail.transport.protocol", "sm ...
- 发送邮件(遵循smtp协议即简单的邮件发送协议)
HandleSendEmail.aspx逻辑 protected void Page_Load(object sender,EventArgs e) { foreach(var item in Req ...
随机推荐
- 科学计算:Python 分析数据找问题,并图形化
对于记录的数据,如何用 Python 进行分析.或图形化呢? 本文将介绍 numpy, matplotlib, pandas, scipy 几个包,进行数据分析.与图形化. 准备环境 Python 环 ...
- PyCharm罢工并向你丢出了pip升级需求
一.事件缘由 最近在搞接口自动化框架,基于python自然少不了使用PyCharm.本来都是 在解决脚本上遇到的坑,突然出现了第三方库安装失败,这感觉就像大热天吃到 冰激凌,昏沉的脑袋瞬间清醒许多. ...
- cb36a_c++_STL_算法_区间的比较equal_mismatch_lexicographical_compare
*cb36a_c++_STL_算法_区间的比较equal_mismatch_lexicographical_compare 区间:容器中的全部数据或者部分数据,都叫做区间 equal(b,e,b2), ...
- Head_First_Python(中文版)完整版PDF免费下载_百度云盘
Head_First_Python(中文版)完整版PDF免费下载_百度云盘 提取码:bjbg 本书特色 根据认知科学和学习理论的最新研究成果,这本书采用一种适合大脑的丰富格式娓娓道来,而不是长篇累牍地 ...
- SLAM:使用EVO测评ORBSLAM2
SLAM:使用EVO测评ORBSLAM2 EVO是用来评估SLAM系统测量数据以及输出估计优劣的Python工具,详细说明请参照: https://github.com/MichaelGrupp/ev ...
- DNS bind使用
概念介绍 DNS的分类 主DNS:配置管理,不提供服务,只用来编辑配置信息,给从DNS提供同步数据 从DNS:从主DNS上同步数据信息,对外提供服务 缓存DNS:在主DNS和从DNS之间,用来递归解析 ...
- logback.xml 不能被加载,logback不能被执行,logback.xml 无法生效,slf4j日志样式输出失败
1. 原因 logback.xml 无法被加载, 尝试了好久还是失败,哎,最后新建工程竟然可以,所以说还是项目的问题: 原来项目依赖了两个slf4j.jar,是版本冲突了: 2. 查找原因 idea ...
- 03.基于测试开发讲解和Cobertura框架介绍
首先我们先 CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(200) DEFAULT ...
- 九、深度优先 && 广度优先
原文地址 一.什么是"搜索"算法? 算法是作用于具体数据结构之上的,深度优先搜索算法和广度优先搜索算法都是基于"图"这种数据结构的. 因为图这种数据结构的表达能 ...
- 只需几行 JavaScript 代码,网页瞬间有气质了!
最近在网上闲逛,发现一个特别好玩的 JavaScript 库,叫 RoughNotation.干嘛用的呢?就是在网页上给文字加标注,比如下划线.方框.高亮文字背景等,不过是手写风格的!截图给大家感受下 ...