无须SMTP服务器中转直接发送电子邮件
本作品内容为无须SMTP服务器中转直接发送电子邮件,格式为 doc ,大小 113152 KB ,页数为 12页
('无须SMTP服务器中转直接发送电子邮件前言大伙儿一定熟悉Foxmail中的“特快专递”,它能直截了当将电子邮件发送到对方的邮件服务器中,而不需要通过SMTP服务器中转,如此做有什么好处?第一:发送速度比较快,不需要等SMTP服务器对邮件进行查毒、派发、验证;第二:你能够及时把握邮件是否发送成功的信息。有时我们用Outlook发送一封邮件,到翌日对方都没收到,可我这边确实差不多发送成功了,只好让对方多收几次,到了第三天SMTP服务器回信说“不行意思,你发往XXX的邮件因为XXX缘故未能送达……”,原先邮件被打回来了,专门最近163邮箱专门离谱,我发出去的10封邮件,至少有3封会被无故打回来,说什么“网络连接失败”因此被打回,莫名其妙,可能我是免费邮箱的缘故吧,没方法只好再申请多几个邮箱,我现在差不多有“chrys@21cn、chrys.xie@gmail、hwxie@ust.hk……”好多邮箱了,确实是为了防止给别人发邮件时被无故退回……扯远了,不行意思。第三:我们有时需要在程序里将某些敏锐信息发送至公司邮箱,例如:运算注册码时我们需要用户操作我们的软件将申请注册的信息发送回我们的售后服务邮箱,由我们的工作人员处理来这些邮件。大伙儿一定会想用SMTP(SimpleMailTransferProtocol)借助SMTP服务器也能通过程序实现邮件发送,然而有一个专门大问题确实是安全问题,专门多闻名的邮件服务器运营商关于用软件方式通过SMTP协议频繁提交邮件转发的申请是不欢迎的,我的163邮箱就曾经深受其害,我那次是在写SMTP客户端发送邮件的程序,顺手就用了163的SMTP服务器,我刚发到第5封邮件时就发送失败了,我再登录163网站一查,原先我的账号被封了,缘故确实是我用软件发送邮件太多了(天啦,才5封而已啊),后来我花了近两个月时刻跟新浪公司又赔礼又道歉,还把身份证过去了我的账号才被复原。剖析邮件传送过程废话说太多请别介意,现在言归正传,要直截了当将邮件送到对方(POP或IMAP)服务器上,而不通过SMTP邮件服务器转交,事实上也不难,你只要改用Unix/Linux操作系统,直截了当SendMail命令就能完成,但在Windows下想要实现那个功能可能得花一点心思了。我们第一要从协议RFC821-SimpleMailTransferProtocol入手来分析。第一我们看一下Email的递送过程:邮件原文→编码→SMTP客户端→SMTP转交服务器→远程SMTP服务器(对方邮局)。“特快专递”的实现思路邮件编码后被递送到一个SMTP转交服务器上,该服务器对信件分检(到同一邮局的被放在一起)后,依照优先级以及信件的先后次序被发送到远程邮局的SMTP服务器上。换句话说,只要我们明白了SMTP转交服务器是如何确定远程邮局SMTP服务器的地址的,就能够直截了当递送到远程邮局服务器。SMTP转交服务器又是明白远程邮局的地址呢?这确实是域名解析所完成的工作了,就好比我们在IE扫瞄器输入“viction.net”那个域名,IE扫瞄器又如何明白目标服务器的IP地址呢?也是域名解析服务器的功劳。电子邮件地址由两部分组成,例如:chrys@163,那个地点的chrys是邮箱名(即用户名,一个用户对应一个邮箱),163是邮箱服务器地址,邮箱名和邮箱服务器地址之间以“@”作为分隔。我们只要向域名服务器发送查询“163”的远程邮局服务器地址便可找到远程邮局SMTP服务器的IP地址,该查询指令被称作MX(MailExchange)邮件交换服务器的地址查询。远程邮局SMTP服务器的地址可能不止一个,这时,你可依照信件优先级的不同来选择对应的远程邮局,我为了安全起见会对每一个远程邮局服务器按照等级高低逐一尝试,只要将邮件成功地发送到其中一个邮局我们的任务就完成了。我们要完成几项编程工作:本机DNS的猎取、与DNS服务器通信实现MX指令查询、SMTP邮件提交,下面我们一一阐述。猎取本机DNS代码中我封装了一个类CnetAdapterInfo,该类能够猎取本机网卡的系列信息,包括本机IP地址、子网掩码、DNS、Wins、网卡MAC地址等相关信息。第一我们需要调用IPHelpAPI库中的GetAdaptersInfo()函数来猎取系统中所有网卡信息。DWORDGetAdaptersInfo(__outPIP_ADAPTER_INFOpAdapterInfo,__inoutPULONGpOutBufLen);该函数有两个参数,pAdapterInfo是一个指针,指向一个用户定义的结构体,一样是用HeapAlloc()申请的内存空间,pOutBufLen传入pAdapterInfo所指空间的大小,传出实际需要的缓冲大小,第一次调用该函数时pOutBufLen传入0,函数将返回ERROR_BUFFER_OVERFLOW表示需要更多的缓冲,并将实际需要的缓冲长度返回,我们依照实际长度用HeapAlloc()函数申请空间再次调用该函数,以下代码是枚举所有网卡并将信息储存到数组m_Ary_NetAdapterInfo中:#defineMALLOC(bytes)::HeapAlloc(::GetProcessHeap(),HEAP_ZERO_MEMORY,(bytes))#defineFREE(ptr)if(ptr)::HeapFree(::GetProcessHeap(),0,ptr)#defineREMALLOC(ptr,bytes)::HeapReAlloc(::GetProcessHeap(),HEAP_ZERO_MEMORY,ptr,bytes)////枚举网络适配器//return:------------------------------------------------------------//-1-失败//>=0-网络适配器数量//intCNetAdapterInfo::EnumNetworkAdapters(){DeleteAllNetAdapterInfo();IP_ADAPTER_INFOpAdptInfo=NULL;IP_ADAPTER_INFOpNextAd=NULL;ULONGulLen=0;intnCnt=0;DWORDdwError=::GetAdaptersInfo(pAdptInfo,&ulLen);if(dwError!=ERROR_BUFFER_OVERFLOW)return-1;pAdptInfo=(IP_ADAPTER_INFO)MALLOC(ulLen);dwError=::GetAdaptersInfo(pAdptInfo,&ulLen);if(dwError!=ERROR_SUCCESS)return-1;pNextAd=pAdptInfo;while(pNextAd){COneNetAdapterInfopOneNetAdapterInfo=newCOneNetAdapterInfo(pNextAd);if(pOneNetAdapterInfo){m_Ary_NetAdapterInfo.Add(pOneNetAdapterInfo);}nCnt++;pNextAd=pNextAd->Next;}//freeanymemoryweallocatedfromtheheapbefore//exit.wewouldn\'twannaleavememoryleaksnowwouldwe?;pFREE(pAdptInfo);returnnCnt;}针对每个网卡信息,我们需要调用GetPerAdapterInfo()函数来猎取指定网卡的DNS信息,使用方法和GetAdaptersInfo()类似。以下代码猎取网卡差不多信息:////依照传入的pAdptInfo信息来猎取指定网卡的差不多信息//BOOLCOneNetAdapterInfo::Init(){IP_ADDR_STRINGpNext=NULL;IP_PER_ADAPTER_INFOpPerAdapt=NULL;ULONGulLen=0;DWORDdwErr=ERROR_SUCCESS;ASSERT(m_AdptInfo.AddressLength>0);t_IPINFOiphold;//将变量清空m_bInitOk=FALSE;m_csName.Empty();m_csDesc.Empty();m_CurIPInfo.csIP.Empty();m_CurIPInfo.csSubnet.Empty();m_Ary_IP.RemoveAll();m_Ary_DNS.RemoveAll();m_Ary_Gateway.RemoveAll();#ifndef_UNICODEm_csName=m_AdptInfo.AdapterName;m_csDesc=m_AdptInfo.Description;#elseUSES_CONVERSION;m_csName=A2W(m_AdptInfo.AdapterName);m_csDesc=A2W(m_AdptInfo.Description);#endif//猎取当前正在使用的IP地址if(m_AdptInfo.CurrentIpAddress){m_CurIPInfo.csIP=m_AdptInfo.CurrentIpAddress->IpAddress.String;m_CurIPInfo.csSubnet=m_AdptInfo.CurrentIpAddress->IpMask.String;}else{m_CurIPInfo.csIP=_T("0.0.0.0");m_CurIPInfo.csSubnet=_T("0.0.0.0");}//猎取本网卡中所有的IP地址pNext=&(m_AdptInfo.IpAddressList);while(pNext){iphold.csIP=pNext->IpAddress.String;iphold.csSubnet=pNext->IpMask.String;m_Ary_IP.Add(iphold);pNext=pNext->Next;}//猎取本网卡中所有的网关信息pNext=&(m_AdptInfo.GatewayList);while(pNext){m_Ary_Gateway.Add(pNext->IpAddress.String);pNext=pNext->Next;}//猎取本网卡中所有的DNSdwErr=::GetPerAdapterInfo(m_AdptInfo.Index,pPerAdapt,&ulLen);if(dwErr==ERROR_BUFFER_OVERFLOW){pPerAdapt=(IP_PER_ADAPTER_INFO)MALLOC(ulLen);dwErr=::GetPerAdapterInfo(m_AdptInfo.Index,pPerAdapt,&ulLen);//ifwesucceedthanweneedtodropintoourloop//andfillthednsarraywillallavailableIP//addresses.if(dwErr==ERROR_SUCCESS){pNext=&(pPerAdapt->DnsServerList);while(pNext){m_Ary_DNS.Add(pNext->IpAddress.String);pNext=pNext->Next;}m_bInitOk=TRUE;}//thisisdoneoutsidethedwErr==ERROR_SUCCESjustincase.themacro//usesNULLpointercheckingsoitisokifpPerAdaptwasneverallocated.FREE(pPerAdapt);}returnm_bInitOk;}至此我们差不多猎取到系统中所有DNS服务器地址了。MX指令查询猎取远程邮局地址与DNS服务器通信事实上确实是一个简单的UDP网络通信,端口号为53,通信的数据格式如下:所有的DNS消息差不多上差不多上相同的数据结构,但DNSRR是采纳了其他的数据结构。QNAME是一个表示域长度的变量,表示每一节有多少字节,例如:sockets将表示为:最后的“Additional”通常包含了查询服务器期望被发送的纪录以减少通信量,例如,回应MX查询时通常在“Additional”中包含‘A’纪录。具体的MX查询过程请参加源代码,以下代码实现了猎取本机所有DNS,然后逐一尝试MX查询的方法:////尝试所有的DNS来查询邮局服务器地址//BOOLGetMX(charpszQuery,//要查询的域名OUTt_Ary_MXHostInfos&Ary_MXHostInfos//输出MailExchange主机名){CNetAdapterInfom_NetAdapterInfo;m_NetAdapterInfo.Refresh();intnNetAdapterCount=m_NetAdapterInfo.GetNetCardCount();for(inti=0;i
提供无须SMTP服务器中转直接发送电子邮件会员下载,编号:1700774563,格式为 docx,文件大小为12页,请使用软件:wps,office word 进行编辑,PPT模板中文字,图片,动画效果均可修改,PPT模板下载后图片无水印,更多精品PPT素材下载尽在某某PPT网。所有作品均是用户自行上传分享并拥有版权或使用权,仅供网友学习交流,未经上传用户书面授权,请勿作他用。若您的权利被侵害,请联系963098962@qq.com进行删除处理。