当前位置: 首页 > news >正文

C#开发基于ESMTP协议的邮件发送系统经验总结

用过C#内置的SMTP类的朋友大概知道,使用它发送邮件的时候,有时候总是出现莫名奇妙的错误,有时候可以发送成功,有时候说用户帐号验证失败,即使你设置了帐号验证信息,问题依旧,特别是在你使用QQ邮箱(好像163的用SMTP发送比较正常),基本上使用SMTP对象来发送邮件是不可能的事情,后来查询了一些资料,说QQ的协议好像是ESMTP协议了,也就是加强版的SMTP协议,不知道是不是,反正用QQ邮件的人比较多,发送的问题就比较突出了。
特别是我的软件“QQ号码采集及邮件发送系统”,之前一直使用SMTP类来处理邮件的发送,客户反映QQ邮件发送不成功的问题就特别突出,但是当时不知道如何处理这个问题,晚上找了很多资料,问题依旧,甚是头痛。先看看我这个邮件发送软件的界面先。

这个软件目前已经实现了ESMTP协议的批量发送功能了,测试发现163也支持ESMTP协议,估计大多数的SMTP提供商都是支持这个接口的了,因为对他们来说这个是更加安全、更少垃圾邮件的协议,好像有的像我们日常所说的“实名制”规则一样。
和SMTP类发送邮件不同,ESMTP是通过以流方式向服务器发送TCP/IP命令,进而获得交互响应的模式进行的,如要连接SMTP服务器,首先通过下面代码进行连接。
             // 连接网络
             try
            {
                tc 
=   new  TcpClient(mailserver, mailserverport);
            }
            
catch  (Exception e)
            {
                errmsg 
=  e.ToString();
                
return   false ;
            }

            ns 
=  tc.GetStream();

         ///   <summary>
        
///  接收SMTP服务器回应
        
///   </summary>
         protected   string  RecvResponse()
        {
            
int  StreamSize;
            
string  ReturnValue  =   " false " ;
            
byte [] ReadBuffer  =   new   byte [ 4096 ];

            
try
            {
                StreamSize 
=  ns.Read(ReadBuffer,  0 , ReadBuffer.Length);
            }
            
catch
            {
                errmsg 
=   " 网络连接错误 " ;
                
return  ReturnValue;
            }

            
if  (StreamSize  ==   0 )
            {
                
return  ReturnValue;
            }
            
else
            {
                ReturnValue 
=  Encoding.Default.GetString(ReadBuffer).Substring( 0 , StreamSize).Trim(); ;
                
// logs+=ReturnValue;
                 return  ReturnValue;
            }
        }

一旦获得正常的响应后,就一步步向服务器发送请求命令或者数据来完成其他操作的。
发送命令的函数就是写入网络流的方式,通过下面的命令实现的
         ///   <summary>
        
///  发送SMTP命令
        
///   </summary>     
         protected   bool  SendCommand( string  Command)
        {
            
byte [] WriteBuffer;
            
if  (Command  ==   null   ||  Command.Trim()  ==   "" )
            {
                
return   true ;
            }
            
// logs+=Command;
            WriteBuffer  =  Encoding.Default.GetBytes(Command);
            
try
            {
                ns.Write(WriteBuffer, 
0 , WriteBuffer.Length);
            }
            
catch
            {
                errmsg 
=   " 网络连接错误 " ;
                
return   false ;
            }
            
return   true ;
        }

ESMTP的特点就是需要验证用户,一旦验证用户通过后,用户就可以通过发送各类命令或者数据了,下面简单列出几个命令格式,其他的大家可以查询相关资料进行完成。
             // 发件人信息
            SendBufferstr  =   " MAIL FROM:< "   +  From  +   " > "   +  enter;
            
if  ( ! Dialog(SendBufferstr,  " 发件人地址错误,或不能为空 " ))
                
return   false ;

            
// 收件人列表
            SendBuffer.Clear();
            
foreach  (String item  in  Recipient)
            {
                SendBuffer.Add(
" RCPT TO:< "   +  item  +   " > "   +  enter);
                RecipientName 
=  item; // 这里其实只能支持一个收件人
            }
            
if  ( ! Dialog(SendBuffer,  " 收件人地址有误 " ))
                
return   false ;

使用这个发送邮件,连最难对付的QQ邮箱也飞快的接收到了我的邮件了,不过大家不要滥发邮件,毕竟“实名制”的方式就是要对后果负责的。呵呵。

相关文章:

  • 实习笔记2
  • 十五、不同VLAN之间相互通信的两种方式(单臂路由、三层交换)
  • PB与COM之关于创建COM,MTS, and COM+组件(1)
  • 让Windows Mobile模拟器通过你的PC上网
  • socket在windows下和linux下的区别
  • 还是小孩子。。。。
  • JavaScript 闭包
  • 一台笔记本烦人
  • 一起学DHCP系列(七)租约、释放
  • 没事常看看
  • 数据链路层plus——TCP/IP Review
  • [转]NHibernate文章转载
  • 解决方案:诊断帐号被Lockout的原因
  • 深入解析跨站请求伪造漏洞(转)
  • 邮件服务器解决方案
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • __proto__ 和 prototype的关系
  • 【笔记】你不知道的JS读书笔记——Promise
  • echarts的各种常用效果展示
  • emacs初体验
  • express.js的介绍及使用
  • gulp 教程
  • mysql 5.6 原生Online DDL解析
  • spring学习第二天
  • 给初学者:JavaScript 中数组操作注意点
  • 前端之React实战:创建跨平台的项目架构
  • 用Visual Studio开发以太坊智能合约
  • 怎么把视频里的音乐提取出来
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • ​批处理文件中的errorlevel用法
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • # 达梦数据库知识点
  • #{} 和 ${}区别
  • #NOIP 2014# day.2 T2 寻找道路
  • (1)常见O(n^2)排序算法解析
  • (二)PySpark3:SparkSQL编程
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (强烈推荐)移动端音视频从零到上手(下)
  • (转)EOS中账户、钱包和密钥的关系
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • .net项目IIS、VS 附加进程调试
  • @Bean注解详解
  • @javax.ws.rs Webservice注解
  • @RunWith注解作用
  • @selector(..)警告提示
  • [20150321]索引空块的问题.txt
  • [2016.7 day.5] T2
  • [CLickhouse] 学习小计
  • [CLR via C#]11. 事件
  • [Codeforces1137D]Cooperative Game
  • [Docker]五.Docker中Dockerfile详解