SmtpServerHelper.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926
  1. using System;
  2. using System.Text;
  3. using System.IO;
  4. using System.Net.Sockets;
  5. using System.Collections;
  6. namespace Ant.Service.Utilities
  7. {
  8. public enum MailFormat { Text, HTML };
  9. public enum MailPriority { Low = 1, Normal = 3, High = 5 };
  10. /// <summary>
  11. /// 添加附件
  12. /// </summary>
  13. public class MailAttachments
  14. {
  15. #region 构造函数
  16. public MailAttachments()
  17. {
  18. _Attachments = new ArrayList();
  19. }
  20. #endregion
  21. #region 私有字段
  22. private IList _Attachments;
  23. private const int MaxAttachmentNum = 10;
  24. #endregion
  25. #region 索引器
  26. public string this[int index]
  27. {
  28. get { return (string)_Attachments[index]; }
  29. }
  30. #endregion
  31. #region 公共方法
  32. /// <summary>
  33. /// 添加邮件附件
  34. /// </summary>
  35. /// <param name="FilePath">附件的绝对路径</param>
  36. public void Add(params string[] filePath)
  37. {
  38. if (filePath == null)
  39. {
  40. throw (new ArgumentNullException("非法的附件"));
  41. }
  42. else
  43. {
  44. for (int i = 0; i < filePath.Length; i++)
  45. {
  46. Add(filePath[i]);
  47. }
  48. }
  49. }
  50. /// <summary>
  51. /// 添加一个附件,当指定的附件不存在时,忽略该附件,不产生异常。
  52. /// </summary>
  53. /// <param name="filePath">附件的绝对路径</param>
  54. public void Add(string filePath)
  55. {
  56. if (System.IO.File.Exists(filePath))
  57. {
  58. if (_Attachments.Count < MaxAttachmentNum)
  59. {
  60. _Attachments.Add(filePath);
  61. }
  62. }
  63. }
  64. /// <summary>
  65. /// 清除所有附件
  66. /// </summary>
  67. public void Clear()
  68. {
  69. _Attachments.Clear();
  70. }
  71. /// <summary>
  72. /// 获取附件个数
  73. /// </summary>
  74. public int Count
  75. {
  76. get { return _Attachments.Count; }
  77. }
  78. #endregion
  79. }
  80. /// <summary>
  81. /// 邮件信息
  82. /// </summary>
  83. public class MailMessage
  84. {
  85. #region 构造函数
  86. public MailMessage()
  87. {
  88. _Recipients = new ArrayList(); //收件人列表
  89. _Attachments = new MailAttachments(); //附件
  90. _BodyFormat = MailFormat.HTML; //缺省的邮件格式为HTML
  91. _Priority = MailPriority.Normal;
  92. _Charset = "GB2312";
  93. }
  94. #endregion
  95. #region 私有字段
  96. private int _MaxRecipientNum = 30;
  97. private string _From; //发件人地址
  98. private string _FromName; //发件人姓名
  99. private IList _Recipients; //收件人
  100. private MailAttachments _Attachments;//附件
  101. private string _Body; //内容
  102. private string _Subject; //主题
  103. private MailFormat _BodyFormat; //邮件格式
  104. private string _Charset = "GB2312"; //字符编码格式
  105. private MailPriority _Priority; //邮件优先级
  106. #endregion
  107. #region 公有属性
  108. /// <summary>
  109. /// 设定语言代码,默认设定为GB2312,如不需要可设置为""
  110. /// </summary>
  111. public string Charset
  112. {
  113. get { return _Charset; }
  114. set { _Charset = value; }
  115. }
  116. /// <summary>
  117. /// 最大收件人
  118. /// </summary>
  119. public int MaxRecipientNum
  120. {
  121. get { return _MaxRecipientNum; }
  122. set { _MaxRecipientNum = value; }
  123. }
  124. /// <summary>
  125. /// 发件人地址
  126. /// </summary>
  127. public string From
  128. {
  129. get { return _From; }
  130. set { _From = value; }
  131. }
  132. /// <summary>
  133. /// 发件人姓名
  134. /// </summary>
  135. public string FromName
  136. {
  137. get { return _FromName; }
  138. set { _FromName = value; }
  139. }
  140. /// <summary>
  141. /// 内容
  142. /// </summary>
  143. public string Body
  144. {
  145. get { return _Body; }
  146. set { _Body = value; }
  147. }
  148. /// <summary>
  149. /// 主题
  150. /// </summary>
  151. public string Subject
  152. {
  153. get { return _Subject; }
  154. set { _Subject = value; }
  155. }
  156. /// <summary>
  157. /// 附件
  158. /// </summary>
  159. public MailAttachments Attachments
  160. {
  161. get { return _Attachments; }
  162. set { _Attachments = value; }
  163. }
  164. /// <summary>
  165. /// 优先权
  166. /// </summary>
  167. public MailPriority Priority
  168. {
  169. get { return _Priority; }
  170. set { _Priority = value; }
  171. }
  172. /// <summary>
  173. /// 收件人
  174. /// </summary>
  175. public IList Recipients
  176. {
  177. get { return _Recipients; }
  178. }
  179. /// <summary>
  180. /// 邮件格式
  181. /// </summary>
  182. public MailFormat BodyFormat
  183. {
  184. set { _BodyFormat = value; }
  185. get { return _BodyFormat; }
  186. }
  187. #endregion
  188. #region 公共方法
  189. /// <summary>
  190. /// 增加一个收件人地址
  191. /// </summary>
  192. /// <param name="recipient">收件人的Email地址</param>
  193. public void AddRecipients(string recipient)
  194. {
  195. if (_Recipients.Count < MaxRecipientNum)
  196. {
  197. _Recipients.Add(recipient);
  198. }
  199. }
  200. /// <summary>
  201. /// 增加多个收件人地址
  202. /// </summary>
  203. /// <param name="recipient">收件人的Email地址集合</param>
  204. public void AddRecipients(params string[] recipient)
  205. {
  206. if (recipient == null)
  207. {
  208. throw (new ArgumentException("收件人不能为空."));
  209. }
  210. else
  211. {
  212. for (int i = 0; i < recipient.Length; i++)
  213. {
  214. AddRecipients(recipient[i]);
  215. }
  216. }
  217. }
  218. #endregion
  219. }
  220. /// <summary>
  221. /// 邮件操作
  222. /// </summary>
  223. public class SmtpServerHelper
  224. {
  225. #region 构造函数、析构函数
  226. public SmtpServerHelper()
  227. {
  228. SMTPCodeAdd();
  229. }
  230. ~SmtpServerHelper()
  231. {
  232. networkStream.Close();
  233. tcpClient.Close();
  234. }
  235. #endregion
  236. #region 私有字段
  237. /// <summary>
  238. /// 回车换行
  239. /// </summary>
  240. private string CRLF = "\r\n";
  241. /// <summary>
  242. /// 错误消息反馈
  243. /// </summary>
  244. private string errmsg;
  245. /// <summary>
  246. /// TcpClient对象,用于连接服务器
  247. /// </summary>
  248. private TcpClient tcpClient;
  249. /// <summary>
  250. /// NetworkStream对象
  251. /// </summary>
  252. private NetworkStream networkStream;
  253. /// <summary>
  254. /// 服务器交互记录
  255. /// </summary>
  256. private string logs = "";
  257. /// <summary>
  258. /// SMTP错误代码哈希表
  259. /// </summary>
  260. private Hashtable ErrCodeHT = new Hashtable();
  261. /// <summary>
  262. /// SMTP正确代码哈希表
  263. /// </summary>
  264. private Hashtable RightCodeHT = new Hashtable();
  265. #endregion
  266. #region 公有属性
  267. /// <summary>
  268. /// 错误消息反馈
  269. /// </summary>
  270. public string ErrMsg
  271. {
  272. set { errmsg = value; }
  273. get { return errmsg; }
  274. }
  275. #endregion
  276. #region 私有方法
  277. /// <summary>
  278. /// 将字符串编码为Base64字符串
  279. /// </summary>
  280. /// <param name="str">要编码的字符串</param>
  281. private string Base64Encode(string str)
  282. {
  283. byte[] barray;
  284. barray = Encoding.Default.GetBytes(str);
  285. return Convert.ToBase64String(barray);
  286. }
  287. /// <summary>
  288. /// 将Base64字符串解码为普通字符串
  289. /// </summary>
  290. /// <param name="str">要解码的字符串</param>
  291. private string Base64Decode(string str)
  292. {
  293. byte[] barray;
  294. barray = Convert.FromBase64String(str);
  295. return Encoding.Default.GetString(barray);
  296. }
  297. /// <summary>
  298. /// 得到上传附件的文件流
  299. /// </summary>
  300. /// <param name="FilePath">附件的绝对路径</param>
  301. private string GetStream(string FilePath)
  302. {
  303. System.IO.FileStream FileStr = new System.IO.FileStream(FilePath, System.IO.FileMode.Open);
  304. byte[] by = new byte[System.Convert.ToInt32(FileStr.Length)];
  305. FileStr.Read(by, 0, by.Length);
  306. FileStr.Close();
  307. return (System.Convert.ToBase64String(by));
  308. }
  309. /// <summary>
  310. /// SMTP回应代码哈希表
  311. /// </summary>
  312. private void SMTPCodeAdd()
  313. {
  314. ErrCodeHT.Add("421", "服务未就绪,关闭传输信道");
  315. ErrCodeHT.Add("432", "需要一个密码转换");
  316. ErrCodeHT.Add("450", "要求的邮件操作未完成,邮箱不可用(例如,邮箱忙)");
  317. ErrCodeHT.Add("451", "放弃要求的操作;处理过程中出错");
  318. ErrCodeHT.Add("452", "系统存储不足,要求的操作未执行");
  319. ErrCodeHT.Add("454", "临时认证失败");
  320. ErrCodeHT.Add("500", "邮箱地址错误");
  321. ErrCodeHT.Add("501", "参数格式错误");
  322. ErrCodeHT.Add("502", "命令不可实现");
  323. ErrCodeHT.Add("503", "服务器需要SMTP验证");
  324. ErrCodeHT.Add("504", "命令参数不可实现");
  325. ErrCodeHT.Add("530", "需要认证");
  326. ErrCodeHT.Add("534", "认证机制过于简单");
  327. ErrCodeHT.Add("538", "当前请求的认证机制需要加密");
  328. ErrCodeHT.Add("550", "要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问)");
  329. ErrCodeHT.Add("551", "用户非本地,请尝试<forward-path>");
  330. ErrCodeHT.Add("552", "过量的存储分配,要求的操作未执行");
  331. ErrCodeHT.Add("553", "邮箱名不可用,要求的操作未执行(例如邮箱格式错误)");
  332. ErrCodeHT.Add("554", "传输失败");
  333. RightCodeHT.Add("220", "服务就绪");
  334. RightCodeHT.Add("221", "服务关闭传输信道");
  335. RightCodeHT.Add("235", "验证成功");
  336. RightCodeHT.Add("250", "要求的邮件操作完成");
  337. RightCodeHT.Add("251", "非本地用户,将转发向<forward-path>");
  338. RightCodeHT.Add("334", "服务器响应验证Base64字符串");
  339. RightCodeHT.Add("354", "开始邮件输入,以<CRLF>.<CRLF>结束");
  340. }
  341. /// <summary>
  342. /// 发送SMTP命令
  343. /// </summary>
  344. private bool SendCommand(string str)
  345. {
  346. byte[] WriteBuffer;
  347. if (str == null || str.Trim() == String.Empty)
  348. {
  349. return true;
  350. }
  351. logs += str;
  352. WriteBuffer = Encoding.Default.GetBytes(str);
  353. try
  354. {
  355. networkStream.Write(WriteBuffer, 0, WriteBuffer.Length);
  356. }
  357. catch
  358. {
  359. errmsg = "网络连接错误";
  360. return false;
  361. }
  362. return true;
  363. }
  364. /// <summary>
  365. /// 接收SMTP服务器回应
  366. /// </summary>
  367. private string RecvResponse()
  368. {
  369. int StreamSize;
  370. string Returnvalue = String.Empty;
  371. byte[] ReadBuffer = new byte[1024];
  372. try
  373. {
  374. StreamSize = networkStream.Read(ReadBuffer, 0, ReadBuffer.Length);
  375. }
  376. catch
  377. {
  378. errmsg = "网络连接错误";
  379. return "false";
  380. }
  381. if (StreamSize == 0)
  382. {
  383. return Returnvalue;
  384. }
  385. else
  386. {
  387. Returnvalue = Encoding.Default.GetString(ReadBuffer).Substring(0, StreamSize);
  388. logs += Returnvalue + this.CRLF;
  389. return Returnvalue;
  390. }
  391. }
  392. /// <summary>
  393. /// 与服务器交互,发送一条命令并接收回应。
  394. /// </summary>
  395. /// <param name="str">一个要发送的命令</param>
  396. /// <param name="errstr">如果错误,要反馈的信息</param>
  397. private bool Dialog(string str, string errstr)
  398. {
  399. if (str == null || str.Trim() == string.Empty)
  400. {
  401. return true;
  402. }
  403. if (SendCommand(str))
  404. {
  405. string RR = RecvResponse();
  406. if (RR == "false")
  407. {
  408. return false;
  409. }
  410. //检查返回的代码,根据[RFC 821]返回代码为3位数字代码如220
  411. string RRCode = RR.Substring(0, 3);
  412. if (RightCodeHT[RRCode] != null)
  413. {
  414. return true;
  415. }
  416. else
  417. {
  418. if (ErrCodeHT[RRCode] != null)
  419. {
  420. errmsg += (RRCode + ErrCodeHT[RRCode].ToString());
  421. errmsg += CRLF;
  422. }
  423. else
  424. {
  425. errmsg += RR;
  426. }
  427. errmsg += errstr;
  428. return false;
  429. }
  430. }
  431. else
  432. {
  433. return false;
  434. }
  435. }
  436. /// <summary>
  437. /// 与服务器交互,发送一组命令并接收回应。
  438. /// </summary>
  439. private bool Dialog(string[] str, string errstr)
  440. {
  441. for (int i = 0; i < str.Length; i++)
  442. {
  443. if (!Dialog(str[i], ""))
  444. {
  445. errmsg += CRLF;
  446. errmsg += errstr;
  447. return false;
  448. }
  449. }
  450. return true;
  451. }
  452. /// <summary>
  453. /// 连接服务器
  454. /// </summary>
  455. private bool Connect(string smtpServer, int port)
  456. {
  457. try
  458. {
  459. tcpClient = new TcpClient(smtpServer, port);
  460. }
  461. catch (Exception e)
  462. {
  463. errmsg = e.ToString();
  464. return false;
  465. }
  466. networkStream = tcpClient.GetStream();
  467. if (RightCodeHT[RecvResponse().Substring(0, 3)] == null)
  468. {
  469. errmsg = "网络连接失败";
  470. return false;
  471. }
  472. return true;
  473. }
  474. /// <summary>
  475. /// 获取优先级
  476. /// </summary>
  477. /// <param name="mailPriority">优先级</param>
  478. private string GetPriorityString(MailPriority mailPriority)
  479. {
  480. string priority = "Normal";
  481. if (mailPriority == MailPriority.Low)
  482. {
  483. priority = "Low";
  484. }
  485. else if (mailPriority == MailPriority.High)
  486. {
  487. priority = "High";
  488. }
  489. return priority;
  490. }
  491. /// <summary>
  492. /// 发送电子邮件
  493. /// </summary>
  494. /// <param name="smtpServer">发信SMTP服务器</param>
  495. /// <param name="port">端口,默认为25</param>
  496. /// <param name="username">发信人邮箱地址</param>
  497. /// <param name="password">发信人邮箱密码</param>
  498. /// <param name="mailMessage">邮件内容</param>
  499. private bool SendEmail(string smtpServer, int port, bool ESmtp, string username, string password, MailMessage mailMessage)
  500. {
  501. if (Connect(smtpServer, port) == false) return false;
  502. string priority = GetPriorityString(mailMessage.Priority);
  503. bool Html = (mailMessage.BodyFormat == MailFormat.HTML);
  504. string[] SendBuffer;
  505. string SendBufferstr;
  506. //进行SMTP验证
  507. if (ESmtp)
  508. {
  509. SendBuffer = new String[4];
  510. SendBuffer[0] = "EHLO " + smtpServer + CRLF;
  511. SendBuffer[1] = "AUTH LOGIN" + CRLF;
  512. SendBuffer[2] = Base64Encode(username) + CRLF;
  513. SendBuffer[3] = Base64Encode(password) + CRLF;
  514. if (!Dialog(SendBuffer, "SMTP服务器验证失败,请核对用户名和密码。")) return false;
  515. }
  516. else
  517. {
  518. SendBufferstr = "HELO " + smtpServer + CRLF;
  519. if (!Dialog(SendBufferstr, "")) return false;
  520. }
  521. //发件人地址
  522. SendBufferstr = "MAIL FROM:<" + username + ">" + CRLF;
  523. if (!Dialog(SendBufferstr, "发件人地址错误,或不能为空")) return false;
  524. //收件人地址
  525. SendBuffer = new string[mailMessage.Recipients.Count];
  526. for (int i = 0; i < mailMessage.Recipients.Count; i++)
  527. {
  528. SendBuffer[i] = "RCPT TO:<" + (string)mailMessage.Recipients[i] + ">" + CRLF;
  529. }
  530. if (!Dialog(SendBuffer, "收件人地址有误")) return false;
  531. SendBufferstr = "DATA" + CRLF;
  532. if (!Dialog(SendBufferstr, "")) return false;
  533. //发件人姓名
  534. SendBufferstr = "From:" + mailMessage.FromName + "<" + mailMessage.From + ">" + CRLF;
  535. if (mailMessage.Recipients.Count == 0)
  536. {
  537. return false;
  538. }
  539. else
  540. {
  541. SendBufferstr += "To:=?" + mailMessage.Charset.ToUpper() + "?B?" + Base64Encode((string)mailMessage.Recipients[0]) + "?=" + "<" + (string)mailMessage.Recipients[0] + ">" + CRLF;
  542. }
  543. SendBufferstr += ((mailMessage.Subject == String.Empty || mailMessage.Subject == null) ? "Subject:" : ((mailMessage.Charset == "") ? ("Subject:" + mailMessage.Subject) : ("Subject:" + "=?" + mailMessage.Charset.ToUpper() + "?B?" + Base64Encode(mailMessage.Subject) + "?="))) + CRLF;
  544. SendBufferstr += "X-Priority:" + priority + CRLF;
  545. SendBufferstr += "X-MSMail-Priority:" + priority + CRLF;
  546. SendBufferstr += "Importance:" + priority + CRLF;
  547. SendBufferstr += "X-Mailer: Lion.Web.Mail.SmtpMail Pubclass [cn]" + CRLF;
  548. SendBufferstr += "MIME-Version: 1.0" + CRLF;
  549. if (mailMessage.Attachments.Count != 0)
  550. {
  551. SendBufferstr += "Content-Type: multipart/mixed;" + CRLF;
  552. SendBufferstr += " boundary=\"=====" + (Html ? "001_Dragon520636771063_" : "001_Dragon303406132050_") + "=====\"" + CRLF + CRLF;
  553. }
  554. if (Html)
  555. {
  556. if (mailMessage.Attachments.Count == 0)
  557. {
  558. SendBufferstr += "Content-Type: multipart/alternative;" + CRLF; //内容格式和分隔符
  559. SendBufferstr += " boundary=\"=====003_Dragon520636771063_=====\"" + CRLF + CRLF;
  560. SendBufferstr += "This is a multi-part message in MIME format." + CRLF + CRLF;
  561. }
  562. else
  563. {
  564. SendBufferstr += "This is a multi-part message in MIME format." + CRLF + CRLF;
  565. SendBufferstr += "--=====001_Dragon520636771063_=====" + CRLF;
  566. SendBufferstr += "Content-Type: multipart/alternative;" + CRLF; //内容格式和分隔符
  567. SendBufferstr += " boundary=\"=====003_Dragon520636771063_=====\"" + CRLF + CRLF;
  568. }
  569. SendBufferstr += "--=====003_Dragon520636771063_=====" + CRLF;
  570. SendBufferstr += "Content-Type: text/plain;" + CRLF;
  571. SendBufferstr += ((mailMessage.Charset == "") ? (" charset=\"iso-8859-1\"") : (" charset=\"" + mailMessage.Charset.ToLower() + "\"")) + CRLF;
  572. SendBufferstr += "Content-Transfer-Encoding: base64" + CRLF + CRLF;
  573. SendBufferstr += Base64Encode("邮件内容为HTML格式,请选择HTML方式查看") + CRLF + CRLF;
  574. SendBufferstr += "--=====003_Dragon520636771063_=====" + CRLF;
  575. SendBufferstr += "Content-Type: text/html;" + CRLF;
  576. SendBufferstr += ((mailMessage.Charset == "") ? (" charset=\"iso-8859-1\"") : (" charset=\"" + mailMessage.Charset.ToLower() + "\"")) + CRLF;
  577. SendBufferstr += "Content-Transfer-Encoding: base64" + CRLF + CRLF;
  578. SendBufferstr += Base64Encode(mailMessage.Body) + CRLF + CRLF;
  579. SendBufferstr += "--=====003_Dragon520636771063_=====--" + CRLF;
  580. }
  581. else
  582. {
  583. if (mailMessage.Attachments.Count != 0)
  584. {
  585. SendBufferstr += "--=====001_Dragon303406132050_=====" + CRLF;
  586. }
  587. SendBufferstr += "Content-Type: text/plain;" + CRLF;
  588. SendBufferstr += ((mailMessage.Charset == "") ? (" charset=\"iso-8859-1\"") : (" charset=\"" + mailMessage.Charset.ToLower() + "\"")) + CRLF;
  589. SendBufferstr += "Content-Transfer-Encoding: base64" + CRLF + CRLF;
  590. SendBufferstr += Base64Encode(mailMessage.Body) + CRLF;
  591. }
  592. if (mailMessage.Attachments.Count != 0)
  593. {
  594. for (int i = 0; i < mailMessage.Attachments.Count; i++)
  595. {
  596. string filepath = (string)mailMessage.Attachments[i];
  597. SendBufferstr += "--=====" + (Html ? "001_Dragon520636771063_" : "001_Dragon303406132050_") + "=====" + CRLF;
  598. SendBufferstr += "Content-Type: text/plain;" + CRLF;
  599. SendBufferstr += " name=\"=?" + mailMessage.Charset.ToUpper() + "?B?" + Base64Encode(filepath.Substring(filepath.LastIndexOf("\\") + 1)) + "?=\"" + CRLF;
  600. SendBufferstr += "Content-Transfer-Encoding: base64" + CRLF;
  601. SendBufferstr += "Content-Disposition: attachment;" + CRLF;
  602. SendBufferstr += " filename=\"=?" + mailMessage.Charset.ToUpper() + "?B?" + Base64Encode(filepath.Substring(filepath.LastIndexOf("\\") + 1)) + "?=\"" + CRLF + CRLF;
  603. SendBufferstr += GetStream(filepath) + CRLF + CRLF;
  604. }
  605. SendBufferstr += "--=====" + (Html ? "001_Dragon520636771063_" : "001_Dragon303406132050_") + "=====--" + CRLF + CRLF;
  606. }
  607. SendBufferstr += CRLF + "." + CRLF;
  608. if (!Dialog(SendBufferstr, "错误信件信息")) return false;
  609. SendBufferstr = "QUIT" + CRLF;
  610. if (!Dialog(SendBufferstr, "断开连接时错误")) return false;
  611. networkStream.Close();
  612. tcpClient.Close();
  613. return true;
  614. }
  615. #endregion
  616. #region 公有方法
  617. /// <summary>
  618. /// 发送电子邮件,SMTP服务器不需要身份验证
  619. /// </summary>
  620. /// <param name="smtpServer">发信SMTP服务器</param>
  621. /// <param name="port">端口,默认为25</param>
  622. /// <param name="mailMessage">邮件内容</param>
  623. public bool SendEmail(string smtpServer, int port, MailMessage mailMessage)
  624. {
  625. return SendEmail(smtpServer, port, false, "", "", mailMessage);
  626. }
  627. /// <summary>
  628. /// 发送电子邮件,SMTP服务器需要身份验证
  629. /// </summary>
  630. /// <param name="smtpServer">发信SMTP服务器</param>
  631. /// <param name="port">端口,默认为25</param>
  632. /// <param name="username">发信人邮箱地址</param>
  633. /// <param name="password">发信人邮箱密码</param>
  634. /// <param name="mailMessage">邮件内容</param>
  635. public bool SendEmail(string smtpServer, int port, string username, string password, MailMessage mailMessage)
  636. {
  637. return SendEmail(smtpServer, port, true, username, password, mailMessage);
  638. }
  639. #endregion
  640. }
  641. /// <summary>
  642. /// 发送邮件
  643. /// </summary>
  644. //--------------------调用-----------------------
  645. //MailAttachments ma=new MailAttachments();
  646. //ma.Add(@"附件地址");
  647. //MailMessage mail = new MailMessage();
  648. //mail.Attachments=ma;
  649. //mail.Body="你好";
  650. //mail.AddRecipients("zjy99684268@163.com");
  651. //mail.From="zjy99684268@163.com";
  652. //mail.FromName="zjy";
  653. //mail.Subject="Hello";
  654. //SmtpClient sp = new SmtpClient();
  655. //sp.SmtpServer = "smtp.163.com";
  656. //sp.Send(mail, "zjy99684268@163.com", "123456");
  657. //------------------------------------------------
  658. public class SmtpClient
  659. {
  660. #region 构造函数
  661. public SmtpClient()
  662. { }
  663. public SmtpClient(string _smtpServer)
  664. {
  665. _SmtpServer = _smtpServer;
  666. }
  667. #endregion
  668. #region 私有字段
  669. private string errmsg;
  670. private string _SmtpServer;
  671. #endregion
  672. #region 公有属性
  673. /// <summary>
  674. /// 错误消息反馈
  675. /// </summary>
  676. public string ErrMsg
  677. {
  678. get { return errmsg; }
  679. }
  680. /// <summary>
  681. /// 邮件服务器
  682. /// </summary>
  683. public string SmtpServer
  684. {
  685. set { _SmtpServer = value; }
  686. get { return _SmtpServer; }
  687. }
  688. #endregion
  689. public bool Send(MailMessage mailMessage, string username, string password)
  690. {
  691. SmtpServerHelper helper = new SmtpServerHelper();
  692. if (helper.SendEmail(_SmtpServer, 25, username, password, mailMessage))
  693. return true;
  694. else
  695. {
  696. errmsg = helper.ErrMsg;
  697. return false;
  698. }
  699. }
  700. }
  701. /// <summary>
  702. /// 操作服务器上邮件
  703. /// </summary>
  704. public class SmtpMail
  705. {
  706. public SmtpMail()
  707. { }
  708. #region 字段
  709. private StreamReader sr;
  710. private StreamWriter sw;
  711. private TcpClient tcpClient;
  712. private NetworkStream networkStream;
  713. #endregion
  714. #region 私有方法
  715. /// <summary>
  716. /// 向服务器发送信息
  717. /// </summary>
  718. private bool SendDataToServer(string str)
  719. {
  720. try
  721. {
  722. sw.WriteLine(str);
  723. sw.Flush();
  724. return true;
  725. }
  726. catch (Exception err)
  727. {
  728. return false;
  729. }
  730. }
  731. /// <summary>
  732. /// 从网络流中读取服务器回送的信息
  733. /// </summary>
  734. private string ReadDataFromServer()
  735. {
  736. string str = null;
  737. try
  738. {
  739. str = sr.ReadLine();
  740. if (str[0] == '-')
  741. {
  742. str = null;
  743. }
  744. }
  745. catch (Exception err)
  746. {
  747. str = err.Message;
  748. }
  749. return str;
  750. }
  751. #endregion
  752. #region 获取邮件信息
  753. /// <summary>
  754. /// 获取邮件信息
  755. /// </summary>
  756. /// <param name="uid">邮箱账号</param>
  757. /// <param name="pwd">邮箱密码</param>
  758. /// <returns>邮件信息</returns>
  759. public ArrayList ReceiveMail(string uid, string pwd)
  760. {
  761. ArrayList EmailMes = new ArrayList();
  762. string str;
  763. int index = uid.IndexOf('@');
  764. string pop3Server = "pop3." + uid.Substring(index + 1);
  765. tcpClient = new TcpClient(pop3Server, 110);
  766. networkStream = tcpClient.GetStream();
  767. sr = new StreamReader(networkStream);
  768. sw = new StreamWriter(networkStream);
  769. if (ReadDataFromServer() == null) return EmailMes;
  770. if (SendDataToServer("USER " + uid) == false) return EmailMes;
  771. if (ReadDataFromServer() == null) return EmailMes;
  772. if (SendDataToServer("PASS " + pwd) == false) return EmailMes;
  773. if (ReadDataFromServer() == null) return EmailMes;
  774. if (SendDataToServer("LIST") == false) return EmailMes;
  775. if ((str = ReadDataFromServer()) == null) return EmailMes;
  776. string[] splitString = str.Split(' ');
  777. int count = int.Parse(splitString[1]);
  778. if (count > 0)
  779. {
  780. for (int i = 0; i < count; i++)
  781. {
  782. if ((str = ReadDataFromServer()) == null) return EmailMes;
  783. splitString = str.Split(' ');
  784. EmailMes.Add(string.Format("第{0}封邮件,{1}字节", splitString[0], splitString[1]));
  785. }
  786. return EmailMes;
  787. }
  788. else
  789. {
  790. return EmailMes;
  791. }
  792. }
  793. #endregion
  794. #region 读取邮件内容
  795. /// <summary>
  796. /// 读取邮件内容
  797. /// </summary>
  798. /// <param name="mailMessage">第几封</param>
  799. /// <returns>内容</returns>
  800. public string ReadEmail(string str)
  801. {
  802. string state = "";
  803. if (SendDataToServer("RETR " + str) == false)
  804. state = "Error";
  805. else
  806. {
  807. state = sr.ReadToEnd();
  808. }
  809. return state;
  810. }
  811. #endregion
  812. #region 删除邮件
  813. /// <summary>
  814. /// 删除邮件
  815. /// </summary>
  816. /// <param name="str">第几封</param>
  817. /// <returns>操作信息</returns>
  818. public string DeleteEmail(string str)
  819. {
  820. string state = "";
  821. if (SendDataToServer("DELE " + str) == true)
  822. {
  823. state = "成功删除";
  824. }
  825. else
  826. {
  827. state = "Error";
  828. }
  829. return state;
  830. }
  831. #endregion
  832. #region 关闭服务器连接
  833. /// <summary>
  834. /// 关闭服务器连接
  835. /// </summary>
  836. public void CloseConnection()
  837. {
  838. SendDataToServer("QUIT");
  839. sr.Close();
  840. sw.Close();
  841. networkStream.Close();
  842. tcpClient.Close();
  843. }
  844. #endregion
  845. }
  846. }