This article is reprinted and may be useful to everyone.
Summary
This article briefly introduces the process of sending emails through the SMTP protocol (RFC2554), and discusses in.. NET using SMTP to send mail from simple to traditional three different solutions, their possible problems and their solutions. -------------------------------------------------------------------------------- Directory
Introduction
. Net smtp class
. Use the CDO component to send emails
. Use Socket to write the email sending program
. Summary
. More information ------------------------------------------------------------------------------------ Introduction
The mail sending function is often used. NET applications, especially those with network functions.. net smtp class library and the other two methods respectively use CDO (Collaboration Data Objects) and Socket to implement the mail sending function. --------------------------------------------------------------------------------. Net smtp class
First, let's introduce the SMTP class that comes with the. NET class library. In the. NET System. Web. Mail namespace, there is a class dedicated to sending Mail using SMTP protocol: SmtpMail, which can meet the most common Mail sending requirements. This class has only one public function -- Send () and one public Attribute-SmtpServer, for example:
You must use the SmtpServer attribute to specify the name (or IP address) of the server that sends the email, and then call
Send () function to Send an email.
The sample code is as follows:
(In C #)
Using System. Web. Mail;
Public void sendMail ()
{
Try
{
System. Web. Mail. MailMessage myMail = new MailMessage ();
MyMail. From = "myaccount@test.com ";
MyMail. To = "myaccount@test.com ";
MyMail. Subject = "MailTest ";
MyMail. Priority = MailPriority. Low;
MyMail. BodyFormat = MailFormat. Text;
MyMail. Body = "Test ";
SmtpMail. SmtpServer = "smarthost"; // your smtp server here SmtpMail. Send (myMail );
}
Catch (Exception e)
{
Throw e;
}
} You can set email attributes in the parameter MailMessage object of the Send function, such as priority and attachment. In addition to taking the MailMessage object as the parameter (such as the above Code), the Send function can also simply take the four main messages of the email (from, to, subject, messageText) called as a string parameter. ------------------------------------------------------------------------------ Use the CDO component to send an email
CDO is short for Collaboration Data Objects. It is a set of high-level COM Object sets and has evolved through several versions, currently, both Windows and Exchange2000 use the CDO2.0 version (cdosys respectively. dll and cdoex. dll ). CDOSYS is built on the SMTP and NNTP protocols and installed as a component of the Windows2000 Server. You can go to the system directory (such as c: \ winnt or c: \ windows) in the system32 subdirectory. dll ).
Compared with the previously described SmtpMail object, the CDO component provides more functions and some functions not provided by the SmtpMail class, such as sending emails through the SMTP server to be authenticated.
The following code shows how to use the CDO component to send emails through the SMTP server to be authenticated:
(In C #)
Public void CDOsendMail ()
{
Try
{
CDO. Message oMsg = new CDO. Message ();
OMsg. From = "myaccount@test.com ";
OMsg. To = "myaccount@test.com ";
OMsg. Subject = "MailTest ";
OMsg. HTMLBody = "CDO. IConfiguration iConfg = oMsg. Configuration;
ADODB. Fields oFields = iConfg. Fields;
OFields ["http://schemas.microsoft.com/cdo/configuration/sendusing"]. Value = 2;
OFields ["http://schemas.microsoft.com/cdo/configuration/sendemailaddress"]
. Value = "myaccount@test.com"; // sender mail
OFields ["http://schemas.microsoft.com/cdo/configuration/smtpaccountname"]
. Value = "myaccount@test.com"; // email account
OFields ["http://schemas.microsoft.com/cdo/configuration/sendusername"]
. Value = "username ";
OFields ["http://schemas.microsoft.com/cdo/configuration/sendpassword"]
. Value = "password ";
OFields ["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"]
. Value = 1;
// Value = 0 indicates the Anonymous authentication method (verification is not required)
// Value = 1 indicates the Basic authentication method (using basic (clear-text) authentication.
// The configuration sendusername/sendpassword or postusername/postpassword fields
Are used to specify credentials .)
// Value = 2 indicates the NTLM Authentication method (Secure Password Authentication in Microsoft Outlook Express)
OFields ["http://schemas.microsoft.com/cdo/configuration/languagecode"]. Value = 0x0804;
OFields ["http://schemas.microsoft.com/cdo/configuration/smtpserver"]. Value = "smtp.21cn.com"; oFields. Update ();
OMsg. BodyPart. Charset = "gb2312 ";
OMsg. HTMLBodyPart. Charset = "gb2312"; oMsg. Send ();
OMsg = null;
}
Catch (Exception e)
{
Throw e;
}
} Note: uninstall cdoex. dll. ------------------------------------------------------------------------------ Use Socket to write an email sending program
Of course, if you think SmtpMail cannot meet your needs and CDO is not straightforward enough, you can only do it yourself. In fact, if you are familiar with Socket programming, it is not difficult to write an email sending program by yourself. The following is an example.
First, let's briefly introduce how the SMTP server with verification uses the AUTH primitive for identity authentication. For detailed definitions, see RFC2554.
The details are as follows:
1) First, use EHLO instead of the original HELO.
2) After the EHLO is successful, the client needs to send the AUTH primitive and negotiate with the server regarding the transmission mode of the user name and password during authentication.
3) if the negotiation succeeds, the server will return a result code starting with 3, which means the user name and password can be passed to the server.
4) Finally, if the verification succeeds, you can start sending emails.
The following is an actual example. In the WinXP Command window, the client connects to the smtp server of 263 by running the "telnet smtp.263.NET 25" Command:
220 Welcome to coremail System (With Anti-Spam) 2.1
EHLO 263.NET
250-19000030.29
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-AUTH LOGIN
250 8 BITMIME
AUTH LOGIN
334 VXNlcm5hbWU6
BXlhY2NvdW50
334 UGFzc3dvcmQ6
BXlwYXNzd29yZA =
235 Authentication successful
Mail from: myaccount@263.NET
250 OK
Rcpt to: myaccount@263.NET
250 OK
Data
354 End data with <CR> <LF>. <CR> <LF>
This is a testing email.
Haha.
.
250 OK: queued as AC5291D6406C4
QUIT
The content above 221 Bye is the whole process of sending emails. Lines 9 to 14th are related to identity authentication:
Auth login 'client Input
334 VXNlcm5hbWU6 'server prompts "Username: ="
BXlhY2NvdW50 'base64 encoding entered by the client "myaccount ="
334 UGFzc3dvcmQ6 'the server prompts "Password: ="
BXlwYXNzd29yZA = 'base64-encoded client input "mypassword ="
235 Authentication successful 'the server is verified
From the above analysis, we can see that in this authentication process, both the server and the client directly pass the plain text that has passed the standard Base64 encoding through the Socket. This process can be easily implemented using C #, or directly added to the original source code.
In addition, some ESMTP servers do not support auth login authentication, only support AUTH CRAM-MD5 authentication. However, the difference between the two is that the text encoding method is different.
The source code for implementing this feature can be found on the SourceForge. NET http://sourceforge.NET/projects/opensmtp-net. A simple pseudo code is given below:
Public void SendMail (MailMessage msg)
{
NetworkStream nwstream = GetConnection (); WriteToStream (ref nwstream, "EHLO" + smtpHost + "\ r \ n ");
String welcomeMsg = ReadFromStream (ref nwstream); // implement HELO command if EHLO is unrecognized.
If (IsUnknownCommand (welcomeMsg ))
{
WriteToStream (ref nwstream, "HELO" + smtpHost + "\ r \ n ");
}
CheckForError (welcomeMsg, ReplyConstants. OK); // Authentication is used if the u/p are supplied
AuthLogin (ref nwstream); WriteToStream (ref nwstream, "mail from: <" + msg. From. Address + "> \ r \ n ");
CheckForError (ReadFromStream (ref nwstream), ReplyConstants. OK); SendRecipientList (ref nwstream, msg. );
SendRecipientList (ref nwstream, msg. CC );
SendRecipientList (ref nwstream, msg. BCC); WriteToStream (ref nwstream, "DATA \ r \ n ");
CheckForError (ReadFromStream (ref nwstream), ReplyConstants. START_INPUT); if (msg. ReplyTo. Name! = Null & msg. ReplyTo. Name. Length! = 0)
{WriteToStream (ref nwstream, "Reply-To: \" "+ msg. ReplyTo. Name +" \ "<" +
Msg. ReplyTo. Address + "> \ r \ n ");}
Else
{WriteToStream (ref nwstream, "Reply-To: <" + msg. ReplyTo. Address + "> \ r \ n ");}
If (msg. From. Name! = Null & msg. From. Name. Length! = 0)
{WriteToStream (ref nwstream, "From: \" "+ msg. From. Name +" \ "<" +
Msg. From. Address + "> \ r \ n ");}
Else
{WriteToStream (ref nwstream, "From: <" + msg. From. Address + "> \ r \ n ");}
WriteToStream (ref nwstream, "To:" + CreateAddressList (msg. To) + "\ r \ n ");
If (msg. CC. Count! = 0)
{WriteToStream (ref nwstream, "CC:" + CreateAddressList (msg. CC) + "\ r \ n");} WriteToStream (ref nwstream, "Subject:" + msg. subject + "\ r \ n"); if (msg. priority! = Null)
{WriteToStream (ref nwstream, "X-Priority:" + msg. Priority + "\ r \ n");} if (msg. Headers. Count> 0)
{
SendHeaders (ref nwstream, msg );
}
If (msg. Attachments. Count> 0 | msg. HtmlBody! = Null)
{
SendMessageBody (ref nwstream, msg );
}
Else
{
WriteToStream (ref nwstream, msg. Body + "\ r \ n ");
}
WriteToStream (ref nwstream, "\ r \ n. \ r \ n ");
CheckForError (ReadFromStream (ref nwstream), ReplyConstants. OK); WriteToStream (ref nwstream, "QUIT \ r \ n ");
CheckForError (ReadFromStream (ref nwstream), ReplyConstants. QUIT); CloseConnection ();
} Private bool AuthLogin (ref NetworkStream nwstream)
{
If (username! = Null & username. Length> 0 &&
Password! = Null & password. Length> 0)
{
WriteToStream (ref nwstream, "auth login \ r \ n ");
If (AuthImplemented (ReadFromStream (ref nwstream )))
{
WriteToStream (ref nwstream, Convert. ToBase64String (
Encoding. ASCII. getBytes (this. username. toCharArray () + "\ r \ n"); CheckForError (ReadFromStream (ref nwstream), ReplyConstants. SERVER_CHALLENGE); WriteToStream (ref nwstream, Convert. toBase64String (Encoding. ASCII. getBytes (
This. password. ToCharArray () + "\ r \ n ");
CheckForError (ReadFromStream (ref nwstream), ReplyConstants. AUTH_SUCCESSFUL );
Return true;
}
}
Return false;
} -------------------------------------------------------------------------------- Summary
This article introduces. NET, the first (using SmtpMail) solution can meet the functional requirements of most of the basic mail sending functions, the second (using the CDO component) and third (using the Socket to write the SMTP class) solutions provide more free and complete customization methods, for example, they can all implement the mail sending function through the SMTP server with authentication that cannot be implemented in the first solution. Remarks
In. net 2.0, sending emails becomes very simple. Public static void SendSMTPEMail (string strSmtpServer, string strFrom, string strFromPass, string strto, string strSubject, string strBody)
{
System. Net. Mail. SmtpClient client = new SmtpClient (strSmtpServer );
Client. usedefacrecredentials = false; // enable Identity Authentication
Client. Credentials = new System. Net. NetworkCredential (strFrom, strFromPass );
Client. DeliveryMethod = SmtpDeliveryMethod. Network;
System. Net. Mail. MailMessage message = new MailMessage (strFrom, strto, strSubject, strBody );
Message. BodyEncoding = System. Text. Encoding. Default;
Message. IsBodyHtml = false; // whether to use an html-format email
// Message. Priority = MailPriority. High; // mail Priority
// Message. Attachments. Add (new Attachment (@ "F: \ My Documents \ message .txt"); // Attachment
// Message. body = new System. IO. streamReader (@ "F: \ My Documents \ ttt.txt", Encoding. default ). readToEnd (); read the email content from a text file
Client. Send (message );
}