內容為通過兩種方式發送郵件--1.C語言發送郵件 2.C#發送郵件
一,C語言進行郵件的發送
C語言發送郵件的步驟的簡單解析:
1.創建TCP連接 socket()
2.連接到郵箱服務器 SOCKADDR_IN,connect()
3.郵箱用戶和密碼認證登錄 "EHLO smtp.163.com\r\n" → "AUTH LOGIN\r\n"
4.發送郵件主題內容
a.發送 "MAIL FROM:<"郵件的發送方地址">\r\n" //
b.發送 "RCPT TO:<"郵件接收方的地址">\r\n"
c.發送 "DATA\r\n"
d.發送郵件頭(From,To,Subject,Date等),郵件體(郵件體可為空)
e.添加附件內容(可以添加多個,附件也可以不添加)
5.退出登錄 發送 "QUIT\r\n"
6.關閉TCP連接 closesocket(connection);
C語言關鍵代碼如下:
//創建TCP連接
1 if ((connection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
2 {
3 return INVALID_SOCKET;
4 }
//連接到郵箱服務器
1 void ConnectToServer(SOCKET connection,const char *serverName)
2 {
3 //設置SockAddr_In地址結構
4 SOCKADDR_IN serAddr;
5 serAddr.sin_family = AF_INET;
6 serAddr.sin_port = htons(SMTP_PORT);
7 //來自 CAsysSocket::Connect()
8 serAddr.sin_addr.s_addr = inet_addr(serverName);
9 if (serAddr.sin_addr.s_addr == INADDR_NONE)
10 {
11 LPHOSTENT lphost;
12 lphost = gethostbyname(serverName);
13 if (lphost != NULL)
14 serAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->S_un.S_addr;
15 else
16 return;
17 }
18 //連接服務器
19 connect(connection, (SOCKADDR *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
20 return;
21 }
//認證登錄
1 //認證登錄
2 BOOL AuthLogin(SOCKET connection, const char *serverName,const char *userAccount, const char *password)
3 {
4 //發送EHLO%SMTP-Server Name% 說明:HELO 是不帶身份驗證的,而 EHLO 是帶身份驗證
5 char szHello[PARA_BUF] = { 0 };
6 sprintf(szHello, "EHLO %s\r\n", serverName); //"EHLO %s\r\n"
7 if (!send_rev(connection, szHello, GENERIC_SUCCESS))
8 return FALSE;
9
10 //發送AUTH LOGIN
11 if (!send_rev(connection, "AUTH LOGIN\r\n", AUTHLOGIN_SUCCESS)) // "AUTH LOGIN\r\n"
12 return FALSE;
13
14 //發送經過Base64編碼的用戶賬號
15 char szAccount[100]={0};
16 base64_encode(userAccount, strlen(userAccount), &szAccount); //base64編碼
17 strcat(szAccount, "\r\n");
18 if (!send_rev(connection, szAccount, AUTHLOGIN_SUCCESS)) //賬號
19 return FALSE;
20
21 //發送經過Base64編碼的密碼
22 char szPassword[100]={0};
23 base64_encode(password, strlen(password), &szPassword);
24 strcat(szPassword, "\r\n");
25 if (!send_rev(connection, szPassword, AUTH_SUCCESS)) //密碼
26 return FALSE;
27 return TRUE;
28 }
//發送郵件(包含了用戶的退出操作QUIT)
1 //發送郵件
2 BOOL SendMail(SOCKET connection,const char *from, const char *to,
3 const char *subject, const char *body,
4 const char *userName,const char *filePath)
5 {
6 char szFrom[PARA_BUF] = { 0 };
7 char szTo[PARA_BUF] = { 0 };
8 char szSubject[PARA_BUF] = { 0 };
9 char szBodyHead[PARA_BUF * 10] = { 0 };
10 char szBody[PARA_BUF * 20] = { 0 };
11
12 char szDateTime[PARA_BUF] = { 0 };
13 char *szContent=NULL;
14 //郵件的內容,包括正文文本信息,附件內容信息等
15 if (!chars_malloc(&szContent, MAX_FILE_SIZE*4/3 + M ) )
16 {
17 return FALSE;
18 }
19
20 //發送Header中的Mail From
21 sprintf(szFrom, "MAIL FROM:<%s>\r\n", from); // MAIL FROM:<%s>\r\n
22 if (!send_rev(connection, szFrom, GENERIC_SUCCESS) )
23 return FALSE;
24
25 //發送Header中RCPT TO
26 sprintf(szTo, "RCPT TO:<%s>\r\n", to); // RCPT TO:<%s>\r\n
27 if (!send_rev(connection, szTo, GENERIC_SUCCESS))
28 return FALSE;
29
30 //發送DATA\r\n
31 if (!send_rev(connection, "DATA\r\n", DATA_SUCCESS)) // DATA\r\n
32 return FALSE;
33
34 //進行 Body 處理
35 sprintf(szFrom, "FROM:%s<%s>\r\n", userName, from); //content
36 sprintf(szTo, "TO:<%s>\r\n", to);
37 time_t ltime = time(NULL);
38 _tzset();
39 sprintf(szDateTime, "Date:%s", ctime(<ime));
40 sprintf(szSubject, "Subject:%s\r\n", subject);
41
42 sprintf(szBodyHead, "X_Mailer:ntSmtp[ch]\r\n", subject);
43 strcat(szBodyHead, "MIME_Version:1.0\r\n");
44 strcat(szBodyHead, "Content- type:multipart/mixed;Boundary=ntSmtp\r\n\r\n");
45 strcat(szBodyHead, "--ntSmtp\r\n");
46 strcat(szBodyHead, "Content-type:text/plain;Charset=gb2312\r\n");
47 strcat(szBodyHead, "Content_Transfer-Encoding:8bit\r\n\r\n");
48
49 sprintf(szBody, "%s\r\n\r\n", body);
50
51 //連接成content的各部分內容
52 strcat(szContent, szFrom);
53 strcat(szContent, szTo);
54 strcat(szContent, szDateTime);
55 strcat(szContent, szSubject);
56 strcat(szContent, szBodyHead);
57 strcat(szContent, szBody);
58
59 if (filePath != NULL)
60 { //將附件內容添加到szContent
61 AppendAttachment( &szContent, filePath);
62 //AppendAttachment(&szContent, filePath);
63 }
64 //添加結束標記
65 strcat(szContent, "\r\n.\r\n"); // \r\n.\r\n
66
67 //發送Content
68 if ( !send_rev(connection, szContent, GENERIC_SUCCESS) )
69 return FALSE;
70
71 //發送Quit,退出登錄
72 if( !send_rev(connection, "QUIT\r\n", QUIT_SUCCESS) ) //"QUIT\r\n"
73 return FALSE;
74
75 free(szContent);
76 return TRUE;
77 }
二,C#進行郵件的發送
通過C#進行郵件的發送,不需要C語言那樣必須把握住連接通信過程中的諸多細節,
如果進行簡單的郵件發送,只需要使用到兩個類,一個是MailMessage類,該類定義了
一封完整郵件多需要的信息(包括郵件的發送方,接收方,主題,正文內容,附件等信息),
另一個是SmtpClient類,該類是用於服務器端的操作,通過該類的對象,你就可以設置
郵箱服務器的地址(例如:smtp.163.com),郵箱的登錄賬號與密碼等,最終通過該類
的對象便可以將MailMessage的信息發送到指定的郵箱了.
C#發送郵件的步驟的簡單解析:
1.創建MailMessage對象,設置MailMessage的相關成員數據; 包括From,To,Subject,Body,Attachments等信息.
2.創建服務器端對象SmtpClient,設置服務器,郵箱賬號,密碼.
3.通過SmtpClient對象,將MailMessage郵件信息發送出去; 可以進行普通的發送以及異步發送(不阻塞線程).
C#關鍵代碼如下:
//異步發送郵件
1 //發送按鈕
2 private void btn_Send_Click(object sender, EventArgs e)
3 {
4 //創建MailMessage對象
5 MailAddress from = new MailAddress("ntsmtp@163.com");
6 MailAddress to = new MailAddress("miaosha5s@sohu.com");
7 MailMessage mailMessage = new MailMessage(from, to) ;
8 mailMessage.Subject="主題";
9 mailMessage.Body="這是一封來自遠方的郵件.";
10
11 Attachment attachment01 = new Attachment("E:\\01.jpg"); //附件
12 Attachment attachment02 = new Attachment("E:\\02.mp3");
13 mailMessage.Attachments.Add(attachment01);
14 mailMessage.Attachments.Add(attachment02);
15
16 //創建SmtpClient對象 郵箱服務器smtp.163.com
17 SmtpClient smtpClient = new SmtpClient("smtp.163.com");
18 smtpClient.UseDefaultCredentials = true;
19 smtpClient.Credentials =
20 new NetworkCredential("郵箱賬號", "登錄密碼"); //郵箱認證登錄
21 //smtpClient.Timeout = 5000;
22 try
23 {
24 //使用異步發送,不會阻塞該線程
25 smtpClient.SendCompleted += new //完成發送調用回調函數
26 SendCompletedEventHandler(SendCompletedCallback);
27 smtpClient.SendAsync(mailMessage, mailMessage);
28 }
29 catch(Exception ex)
30 {
31 mailMessage.Dispose(); //主動釋放資源
32 smtpClient.Dispose();
33 MessageBox.Show("發送失敗! "+System.Environment.NewLine+
34 "錯誤信息:"+ ex.Message);
35 }
36 return;
37 }
//異步發送完成的回調函數:
1 //異步發送郵件完成的回調函數
2 public static void SendCompletedCallback(object sender,
3 AsyncCompletedEventArgs e)
4 {
5 SmtpClient smtpClient = (SmtpClient)sender;
6 //MailMessage mailMessage = (MailMessage)e.UserState;
7 if (e.Cancelled)
8 {
9 MessageBox.Show("Send canceled.");
10 }
11 if (e.Error != null)
12 {
13 MessageBox.Show("錯誤信息: "+e.Error.ToString() );
14 }
15 else
16 {
17 MessageBox.Show("Message Sent.");
18 smtpClient.Dispose();
19 //mailMessage.Dispose();
20 }
21 }
總結:通過兩種方式實現了簡單的郵件發送功能,從中可以比較這兩種語言在實現上的差異性,
C語言的實現更加講究流程和細節,你需要比較深的懂得網絡的相關知識和SMTP的相關協議,
優點是可以更加直接的操作郵件的發送過程,缺點就是實現起來比較繁瑣,容易異常.
C#的實現就更加簡潔明了了,它封裝了郵件發送過程中的很多細節,這些細節對用戶來說並不是
必要的,使用者只需要知道幾個重要的類(MailMessage,SmtpClient類)的使用,而且程序一般會比
C程序要來的穩定,不容易發生異常錯誤.