You have reached the legacy GHI Electronics, LLC website, for the new website please visit here. For the new forum please visit here.

This legacy website will be taken offline at the end of this year. If there is anything that you would like to archive and save for future reference please do so.

SMTP Email Class for Gadgeteer-based Projects by devhammer

Nov. 15, 2011   |   Snippet   |   Unlicensed   |   1516 views

SMTP.cs is a class based on the code for the FEZ email-based door monitor on the wiki:

http://wiki.tinyclr.com/index.php?title=FEZ_Email_based_Door_Monitor

the code has been updated to support the ethernet module that ships with the FEZ Spider Starter Kit, as well as to support SMTP authentication. The class will automatically base64 encode the username and password, if provided, as required by SMTP.

I needed an email client for my gadgeteer project, and since I'm probably not the only one, I figured I'd share it.



Author Version Date
Arcixx 2 08/19 '17 at 10:37am
devhammer 1 05/04 '12 at 01:44pm
1 — Source
  1. using System;
  2. using Microsoft.SPOT;
  3. using System.Text;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using Microsoft.SPOT.Net.NetworkInformation;
  7. using Gadgeteer.Modules.GHIElectronics;
  8. using System.Threading;
  9.  
  10. public class SmtpClient
  11. {
  12. private string _SmtpServerName = null;
  13. private int _Port = 0;
  14. private enum SmtpState
  15. {
  16. NotConnected,
  17. DomainAccepting,
  18. MailFromAccepting,
  19. RecipientAccepting,
  20. DataCommandAccepting,
  21. MessageAccepting,
  22. ConnectionClosing
  23. };
  24.  
  25. SmtpState state;
  26.  
  27. public SmtpClient(string SmtpServerName, Int32 Port)
  28. {
  29. if (Port < 0)
  30. throw new ArgumentOutOfRangeException();
  31. _SmtpServerName = SmtpServerName;
  32. _Port = Port;
  33. }
  34.  
  35. public void Send(string from, string recipient, string subject, string body,
  36. bool authenticate = false, string username = "", string password = "")
  37. {
  38. if (username != "" && password != "")
  39. {
  40. System.Text.Encoding encoding = new System.Text.UTF8Encoding();
  41. username = ConvertBase64.ToBase64String(encoding.GetBytes(username));
  42. password = ConvertBase64.ToBase64String(encoding.GetBytes(password));
  43. }
  44. state = SmtpState.NotConnected;
  45. /* Connect to the Server*/
  46. // Figure out the Server IP Address
  47. IPHostEntry SmtpServerHostEntry = Dns.GetHostEntry(_SmtpServerName);
  48. IPEndPoint SmtpServerEndPoint = new IPEndPoint(SmtpServerHostEntry.AddressList[0],
  49. _Port);
  50. // Establish the connection with SMTP Server
  51. Socket SmtpConnection = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
  52. ProtocolType.Tcp);
  53. SmtpConnection.Connect(SmtpServerEndPoint);
  54. String ResponseStr = null;
  55. while (SmtpConnection.Poll(-1, SelectMode.SelectRead))
  56. {
  57. byte[] ReceiveBuffer = new byte[SmtpConnection.Available];
  58. SmtpConnection.Receive(ReceiveBuffer, ReceiveBuffer.Length, SocketFlags.None);
  59. // The first 3 bytes hold the message number which is enough for us.
  60. ResponseStr = new String(Encoding.UTF8.GetChars(ReceiveBuffer), 0, 3);
  61. int Response = Int16.Parse(ResponseStr);
  62. switch (state)
  63. {
  64. case SmtpState.NotConnected:
  65. if (Response == 220) // Domain service ready.
  66. {
  67. SmtpConnection.Send(Encoding.UTF8.GetBytes("EHLO " +
  68. from.Split(new char[] { '@' })[1] + "\r\n"));
  69. if (authenticate && username != "" && password != "")
  70. {
  71. Thread.Sleep(300);
  72. SmtpConnection.Send(Encoding.UTF8.GetBytes("AUTH LOGIN\r\n"));
  73. Thread.Sleep(300);
  74. SmtpConnection.Send(Encoding.UTF8.GetBytes(username + "\r\n"));
  75. Thread.Sleep(300);
  76. SmtpConnection.Send(Encoding.UTF8.GetBytes(password + "\r\n"));
  77. Thread.Sleep(300);
  78. }
  79. state = SmtpState.DomainAccepting;
  80. }
  81. break;
  82. case SmtpState.DomainAccepting:
  83. if (Response == 250) // auth successful (if authentication enabled).
  84. {
  85. SmtpConnection.Send(Encoding.UTF8.GetBytes("MAIL FROM:<" + from +
  86. ">\r\n"));
  87. state = SmtpState.MailFromAccepting;
  88. }
  89. break;
  90. case SmtpState.MailFromAccepting:
  91. if (Response == 250) // Requested mail action okay, completed.
  92. {
  93. SmtpConnection.Send(Encoding.UTF8.GetBytes("RCPT TO:<" + recipient
  94. + ">\r\n"));
  95. state = SmtpState.RecipientAccepting;
  96. }
  97. break;
  98. case SmtpState.RecipientAccepting:
  99. if (Response == 250) // Requested mail action okay, completed.
  100. {
  101. SmtpConnection.Send(Encoding.UTF8.GetBytes("DATA\r\n"));
  102. state = SmtpState.DataCommandAccepting;
  103. }
  104. break;
  105. case SmtpState.DataCommandAccepting:
  106. if (Response == 354) //Start mail input; end with <CRLF>.<CRLF>.
  107. {
  108. SmtpConnection.Send(Encoding.UTF8.GetBytes("Subject: " + subject +
  109. "\r\n"));
  110. SmtpConnection.Send(Encoding.UTF8.GetBytes("From: " + from +
  111. "\r\n"));
  112. SmtpConnection.Send(Encoding.UTF8.GetBytes("To: " + recipient +
  113. "\r\n\r\n"));
  114. SmtpConnection.Send(Encoding.UTF8.GetBytes(body + "\r\n"));
  115. SmtpConnection.Send(Encoding.UTF8.GetBytes(".\r\n"));
  116. state = SmtpState.MessageAccepting;
  117. }
  118. break;
  119. case SmtpState.MessageAccepting:
  120. if (Response == 250) // Requested mail action okay, completed.
  121. {
  122. SmtpConnection.Send(Encoding.UTF8.GetBytes("QUIT\r\n"));
  123. state = SmtpState.ConnectionClosing;
  124. }
  125. break;
  126. case SmtpState.ConnectionClosing:
  127. if (Response == 221) // Requested mail action okay, completed.
  128. {
  129. SmtpConnection.Close();
  130. return;
  131. }
  132. break;
  133. }
  134. }
  135. SmtpConnection.Close();
  136. throw new Exception("SMTP connection Timeout");
  137. }
  138. }