无须SMTP服务器中转直接发送电子邮件

上传人:lx****y 文档编号:160965813 上传时间:2022-10-12 格式:DOC 页数:16 大小:110KB
返回 下载 相关 举报
无须SMTP服务器中转直接发送电子邮件_第1页
第1页 / 共16页
无须SMTP服务器中转直接发送电子邮件_第2页
第2页 / 共16页
无须SMTP服务器中转直接发送电子邮件_第3页
第3页 / 共16页
点击查看更多>>
资源描述
无须SMP服务器中转直接发送电子邮件前言 大家一定熟悉Fml中的“特快专递”,它能直接将电子邮件发送到对方的邮件服务器中,而不需要经过STP服务器中转,这样做有什么好处?第一:发送速度比较快,不需要等SMP服务器对邮件进行查毒、派发、验证;第二:你可以及时掌握邮件是否发送成功的信息.有时我们用Otlook发送一封邮件,到第二天对方都没收到,可我这边确实已经发送成功了,只好让对方多收几次,到了第三天SMTP服务器回信说“不好意思,你发往XX的邮件因为XX原因未能送达”,原来邮件被打回来了,尤其最近16邮箱非常离谱,我发出去的10封邮件,至少有3封会被无故打回来,说什么“网络连接失败所以被打回,莫名其妙,可能我是免费邮箱的缘故吧,没办法只好再申请多几个邮箱,我现在已经有“chry、csxi、 ”好多邮箱了,就是为了防止给别人发邮件时被无故退回扯远了,不好意思。第三:我们有时需要在程序里将某些敏感信息发送至公司邮箱,例如:计算注册码时我们需要用户操作我们的软件将申请注册的信息发送回我们的售后服务邮箱,由我们的工作人员处理来这些邮件。 大家一定会想用SP(Smplai Transe otocl)借助SMP服务器也能通过程序实现邮件发送,但是有一个很大问题就是安全问题,很多著名的邮件服务器运营商对于用软件方式通过TP协议频繁提交邮件转发的申请是不欢迎的,我的6邮箱就曾经深受其害,我那次是在写SMP客户端发送邮件的程序,顺手就用了163的SMTP服务器,我刚发到第5封邮件时就发送失败了,我再登录163网站一查,原来我的账号被封了,原因就是我用软件发送邮件太多了(天啦,才封而已啊),后来我花了近两个月时间跟新浪公司又赔礼又道歉,还把身份证传真过去了我的账号才被恢复。剖析邮件传送过程 废话说太多请别介意,现在言归正传,要直接将邮件送到对方(O或IMAP)服务器上,而不经过SMTP邮件服务器转交,其实也不难,你只要改用Unix/Linx操作系统,直接SendMa命令就能完成,但在inds下想要实现这个功能恐怕得花一点心思了.我们首先要从协议RFC81 imple MaTansferPrtocol入手来分析. 首先我们看一下Emai的递送过程: 邮件原文 编码 SMTP客户端 STP转交服务器 远程SMT服务器(对方邮局).“特快专递”的实现思路 邮件编码后被递送到一个ST转交服务器上,该服务器对信件分检(到同一邮局的被放在一起)后,根据优先级以及信件的先后次序被发送到远程邮局的MT服务器上。换句话说,只要我们知道了SMP转交服务器是如何确定远程邮局STP服务器的地址的,就可以直接递送到远程邮局服务器。SP转交服务器又是知道远程邮局的地址呢?这就是域名解析所完成的工作了,就好比我们在E浏览器输入“”这个域名,浏览器又如何知道目标服务器的IP地址呢?也是域名解析服务器的功劳. 电子邮件地址由两部分组成,例如:chr,这里的chy是邮箱名(即用户名,一个用户对应一个邮箱),13。com是邮箱服务器地址,邮箱名和邮箱服务器地址之间以“”作为分隔. 我们只要向域名服务器发送查询“16。co的远程邮局服务器地址便可找到远程邮局MTP服务器的I 地址,该查询指令被称作(Mail Echae)邮件交换服务器的地址查询。远程邮局SMT服务器的地址可能不止一个,这时,你可根据信件优先级的不同来选择对应的远程邮局,我为了安全起见会对每一个远程邮局服务器按照等级高低逐一尝试,只要将邮件成功地发送到其中一个邮局我们的任务就完成了.我们要完成几项编程工作:本机DS的获取、与DS服务器通信实现X指令查询、MTP邮件提交,下面我们一一阐述。 获取本机DNS 代码中我封装了一个类CnedaterIno,该类可以获取本机网卡的系列信息,包括本机P地址、子网掩码、Wins、网卡MAC地址等相关信息。首先我们需要调用IHelpAPI 库中的GetAdaptersInfo()函数来获取系统中所有网卡信息。DRD GtAatersInfo(_out PI_ADAPTER_INOpAdatrnfo, _inou ULOGpOuLn); 该函数有两个参数,pAdpterInfo是一个指针,指向一个用户定义的结构体,一般是用Healloc()申请的内存空间,pOutBfLen传入AdapeInfo所指空间的大小,传出实际需要的缓冲大小,第一次调用该函数时pOutBufen传入0,函数将返回 EROR_BUFFROVERFLW 表示需要更多的缓冲,并将实际需要的缓冲长度返回,我们根据实际长度用Heplc()函数申请空间再次调用该函数,以下代码是枚举所有网卡并将信息保存到数组m_rNetApterInfo 中:#defi ALC(bys ) ::HeapAlo( ::GetPocesHeap(),HEP_ZEO_EORY, (byes)#dfe FREE( tr ) f( tr )::HeapFe( ::GetPrcessHeap(),0, ptr)#defin MALLOC( ptr, byt ) :HeapRello( ::Getrcessea(), HEAP_ZERO_MEORY, pr,bye )/ 枚举网络适配器return : - 1 失败/ =0 网络适配器数量/nt CNeAatrInfo::EnuNtokAapters() eleteAlNtapterfo (); IP_AAPTER_INF*pAdptInfo =ULL; I_ADAPER_INFpNxtA = NULL;ULN lL = 0; in nCnt = 0; DWOR dwrror = :GetAtrsIfo ( pAdptn, &ulLen); i( dwror!= ERRO_BUFFEROVERFLOW ) rur -1; pAptIno (IP_DATE_INFO )LC ( ulLen); dwEor ::GedapterInfo( AdtInf, uLen ); f( dwrr != ERRR_SUCCESS )rtur 1; pNextA = pAdptInfo; wile( pNextAd ) nNeAdperInfo peNetAdaperIno = nCOneeAaperIfo ( pNxtAd ); i ( pOneNedterInf ) m_Ary_NedprIno.Ad ( pOneNtAdapternf); nCnt +; pNextA = pNexAd-Next; / ee ay eorywe aocated m t eapbefre / exi. we wldwannalve memr leaks now wouldwe? ; FREE(dptnfo ); return nCn;针对每个网卡信息,我们需要调用 GetAdateIfo()函数来获取指定网卡的NS信息,使用方法和GetAdptrIfo()类似。以下代码获取网卡基本信息:/ 根据传入的pdtIfo 信息来获取指定网卡的基本信息/BOOL COneNtAapterInfo::Init () IP_ADDR_STRIG pNe = NULL; PPR_DATE_INFOpPrAdapt =NULL; LNGlLen ; RDwErr =ERRRUCCES; SER( m_Adptno.AddresLth 0 ); t_IPNF iphol; 将变量清空 mIntO= FALSE; m_csamempty (); msDesc.Empty(); m_rIPInfo。csIPEmpy(); mCuIPno。cSbne.Empty (); Ar_I.RemovAl (); _r_DNemvell (); m_Ary_Gatewy.RmveAl(); #ifnef _UNICD mcNa m_AdptIfo.AdapterNme;m_cDesc =m_AdptInfoDescript;else USE_CONVESI; csNme A2 ( _ApInfo.Aapterme); _csDesc = A2W (mAdptInfo。Dscptin);endif /获取当前正在使用的IP地址 if ( _Adto.CurretIpddres ) mCuPIno。cs m_dptIoCrentIpAddesIpAdress.Strin; m_urIPnfo。csSue= _AdptInfurntIAddss-pMa.Stig;else m_CuIPInfcsIP = _(”0.0。0.0”); CIPnfo。csSbnet= _T(”。0。0); / 获取本网卡中所有的地址 Nxt= (m_AdtIn。pdresList ); wil ( ext) iphol.s pNtIpAddres.Sring; io。csSbne =extpMask。Stng; _AryIP。d ( iphld ); pNxt pNext-Next; /获取本网卡中所有的网关信息 et = ( dpfo.ayLi ); hile ( Next) mr_Gateway.Add ( pNxt-IpAddres。tring ); Next = Next-Net; / 获取本网卡中所有的 DNS dwErr= :ePeAdapteInf( m_Adpo。Index,prAdapt,&lLe ); (d= RRORBUFFEOVERFL ) eAdapt= ( IPPRDTER_IF* ) MALLOC( ulLe ); wErr= ::etPrAdaptrInfo( _AdptIf。nde, rAdap,&uLen ); /f we scceedhan weneedto dro ino our lop / and fi the d ary will l availabl /aesse. if( wErr= RROR_SUCCES ) pex = (pPerAdpt-nSeverLst ); whle( Ne ) _AryDN.Add( ptIAdes。Srn); pNext pNextNex; _IntOk = T; / s is dneoutsi the dwEr = EROR_SUCES just incase. the mcro / us ULL ointrecingsoit is if pPrAdawsnevr llotd。 EE( pPerAdat ); retrn m_bnitOk; 至此我们已经获取到系统中所有DS服务器地址了.M指令查询获取远程邮局地址 与DNS服务器通信其实就是一个简单的DP网络通信,端口号为5,通信的数据格式如下: 所有的DNS消息基本上都是相同的数据结构,但NS R是采用了其他的数据结构。QNE是一个表示域长度的变量,表示每一节有多少字节,例如:将表示为: 最后的“Aditional”通常包含了查询服务器期望被发送的纪录以减少通信量,例如,回应X查询时通常在“dtiol”中包含纪录。 具体的MX查询过程请参加源代码,以下代码实现了获取本机所有DNS,然后逐一尝试MX查询的方法:/ 尝试所有的DNS来查询邮局服务器地址/BO etX ( char*pzQuer, /要查询的域名 OUT t_Ary_MXHostIos &Ary_MXHotInfo /输出 Mal Exchane 主机名 ) CetAdaterIn _NtAdapterInfo; _NetApterInfo.Rfh(); ntnNetAdaptount m_NetAdaptnfo.GetNetrdCut();fo ( nt =; nNdpterCount; i+ ) COneNetAapterInf *pneNeAdapterInfo =mNAdapteno。GetOneNeAdaternfo ( ); if( neNetAaptrIno ) it nNSCont =pOneNetAdaprInGe_DNCoun (); for ( it j=0; jnDNCot; + ) CStng csDNS = pOneNAaperIfoe_DNSddr ( j ); ( etMX( pszQuery, csDNS.GetBffr(0),Ar_XHstInfos) ) rtur RUE; etrn ASE; 如果查询“”的邮局服务器地址,将得到如下的结果: 50 50 5 10 1 用SMT协议给远程邮局直接发送邮件 SMTP是一个简单邮件传输协议,通过TCP连接服务器的5端口号即可进行数据通信,以下是我用telnet手工发送邮件的过程: 其中红色矩形框起来的是服务器回应的数据,绿色矩形框起来的是我手工输入的数据,这里发送的邮件内容为“我是手工发送的电子邮件,邮件被直接发送到chs.xi邮箱中,不需要讨厌的SMP服务器中转,当然,因为这是手工发送的邮件,其内容未经过任何MIE编码,这封邮件可以被Fxmai或Ooo收到,但可能被判为垃圾邮件,因为这封邮件连标题都没有,是无头苍蝇,肯定是垃圾,呵呵关于邮件内容的编码请参考其他相关资料,我有一本书,名叫Visual C+网络通信协议分析与应用实现,这本书有详细的电子邮件编码介绍,可以下载电子文档看看。 当我们知道了SMTP通信的全过程,再编写一个TP网络通信程序处理与SMT服务器请求就不是难事了。本代码中的HwTP类已经封装了整个通信过程,可以发送普通的电子邮件,还可以发送带附件的电子邮件,配合DNS查找,远程邮局地址MX查询便可实现任意邮件直接发送到对方邮箱的功能。 软件操作界面介绍程序执行后界面如下:rom中可以输入一个虚假的邮箱地址,也可以输入真实的邮箱地址(如:21cn的邮箱),但不能输入163的邮箱,否则发送会失败,163邮箱不太欢迎大家用软件方式进行邮件收发,人家要靠这个吃饭嘛。 注意事项 看到这里是否已经很兴奋了,想着要自己写一个SMTP服务器,甚至想要写一个邮局服务器程序,但我觉得恐怕还没那么容易,我用这个软件给我的gole邮箱(gma)发送邮件,很快就能成功收到了,可我尝试过用这种方式给13邮箱和2n邮箱发送邮件时却失败了,发给13时服务器说你的P不被允许,提示信息如下:07。16。216.155 The I youre usi to snd mail noautorized 5057。1osendemail directly tour sver。Pleuse th STP 看来163邮箱只接收大牌邮件服务器发过来的邮件,难怪我们这些免费的163用户发送邮件时常会被退回,原来163服务器还认牌子的,fan!到底要怎么样做才可以直接给16等著名的邮局发邮件呢?不知道用欺骗方式能否成功,请有高手知道解决这个问题的一定要告诉我啊,我的邮箱是:chr,先谢过了! 电子邮件在目前的Intent上被广泛地使用,为了安全很多邮局服务器做了安全认证等诸多限制,我们要想让自己的SMTP服务器能向所有的邮局发邮件,恐怕还得做更多的努力。 结束语 知识就是力量,知识共享将具有推动时代进步的力量。希望我能为中国的软件行业尽一份薄力. 你可以任意修改复制本代码,但请保留版权信息文字不要修改。由于水平有限,错误再所难免,请知情者原谅并告知,多谢!文中如有不足,请您指教!16 / 16
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 大学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!