目錄結構:
1.簡介
郵件傳輸常用的協議有,SMTP、POP3、IMAP4。他們都屬於TCP/IP協議,默認狀態下分別通過TCP端口25,110,和143建立鏈接。
SMTP協議
SMTP的全稱是“Simple Mail Transfer Protocol”,即簡單郵件傳輸協議。它是一組用於從源地址到目的地址傳輸郵件的規范,通過它來控制郵件的中轉方式。SMTP 協議屬於TCP/IP協議簇,它幫助每台計算機在發送或中轉信件時找到下一個目的地。SMTP 服務器就是遵循SMTP協議的發送郵件服務器。SMTP認證,簡單地說就是要求必須在提供了賬戶名和密碼之后才可以登錄 SMTP 服務器,這就使得那些垃圾郵件的散播者無可乘之機。增加 SMTP 認證的目的是為了使用戶避免受到垃圾郵件的侵擾。
POP協議
POP郵局協議負責從郵件服務器中檢索電子郵件。它要求郵件服務器完成下面幾種任務之一:從郵件服務器中檢索郵件並從服務器中刪除這個郵件;從郵件服務器中檢索郵件但不刪除它;不檢索郵件,只是詢問是否有新郵件到達。POP協議支持多用戶互聯網郵件擴展,后者允許用戶在電子郵件上附帶二進制文件,如文字處理文件和電子表格文件等,實際上這樣就可以傳輸任何格式的文件了,包括圖片和聲音文件等。在用戶閱讀郵件時,POP命令所有的郵件信息立即下載到用戶的計算機上,不在服務器上保留。
IMAP協議
互聯網信息訪問協議(IMAP)是一種優於POP的新協議。和POP一樣,IMAP也能下載郵件、從服務器中刪除郵件或詢問是否有新郵件,但IMAP克服了POP的一些缺點。例如,它可以決定客戶機請求郵件服務器提交所收到郵件的方式,請求郵件服務器只下載所選中的郵件而不是全部郵件。客戶機可先閱讀郵件信息的標題和發送者的名字再決定是否下載這個郵件。通過用戶的客戶機電子郵件程序,IMAP可讓用戶在服務器上創建並管理郵件文件夾或郵箱、刪除郵件、查詢某封信的一部分或全部內容,完成所有這些工作時都不需要把郵件從服務器下載到用戶的個人計算機上。
簡單來說,SMTP協議主要是用於發郵件,POP和IMAP協議用於讀取、刪除、下載郵件。結合QQ郵箱和網易郵箱,筆者認為,QQ郵箱更注重POP協議方面,網易郵箱比較注重SMTP協議方面,下面筆者將會對其原由進行闡述,希望對讀者有所幫助。
在利用第三方對QQ郵箱和網易郵箱進行郵件操作之前,需要在各自的后台開啟POP/SMTP服務,並且獲取到授權碼(網易郵箱若關閉客戶端授權碼,則可以直接用登錄密碼)。
2.發送郵件
發送郵件應該使用SMTP協議。有關SMTP協議的具體內容,這里筆者就不再闡述了。
C#對發送郵件的庫封裝得已經比較好了,開發人員可以很方便的完成發送郵件的操作。在System.Net.Mail命名空間中封裝了對發送郵件的操作,下面是使用QQ郵箱發送的案例:
MailMessage message = new MailMessage(); //設置發件人,發件人需要與設置的郵件發送服務器的郵箱一致 MailAddress fromAddr = new MailAddress("2965372061@qq.com"); message.From = fromAddr; //設置收件人,可添加多個,添加方法與下面的一樣 message.To.Add("2965372061@qq.com"); //設置抄送人 message.CC.Add("2965372061@qq.com"); //設置郵件標題 message.Subject = "通知"; //設置郵件內容 message.Body = "Hello world"; //設置郵件發送服務器,服務器根據你使用的郵箱而不同,可以到相應的 郵箱管理后台查看 SmtpClient client = new SmtpClient("smtp.qq.com", 25); //設置發送人的郵箱賬號和授權碼 client.Credentials = new NetworkCredential("2965372061@qq.com", "授權碼"); //啟用ssl,也就是安全發送 client.EnableSsl = true; //發送郵件 client.Send(message); Console.WriteLine("發送成功"); Console.ReadLine();
上面發送的是文本格式,接下來介紹如何發送HTML格式的文件。如何想要發送HTML格式的郵件,那么只需要指定IsBodyHtml為true即可。
message.Body="<h1>Hello World</h1>"; message.IsBodyHtml=true;
如果想要發送附件的話,那么應該往Message實例中的Attachments 屬性中添加一個Attachment(附件)實例。
關於QQ郵件的發送就討論到這里,接下來討論一下網易郵件的發送。網易郵件的發送較為麻煩,這和網易郵箱的反垃圾郵件機制有關。網易為了希望用戶能夠得到純凈的電子郵件網絡環境,減少垃圾郵件,系統對會對發送的信件做判定,並限制對垃圾的郵件的發送。
下面是網易發送郵件的代碼,筆者測試能夠成功發送郵件:
MailMessage message = new MailMessage(); //設置發件人,發件人需要與設置的郵件發送服務器的郵箱一致 MailAddress fromAddr = new MailAddress("18011389221@163.com"); message.From = fromAddr; message.To.Add("18011389221@163.com");//自己接收 //設置郵件標題 message.Subject = "通知"; //設置郵件內容 message.Body = "Hello world"; //設置郵件發送服務器,服務器根據你使用的郵箱而不同,可以到相應的 郵箱管理后台查看 SmtpClient client = new SmtpClient("smtp.163.com", 25); //設置發送人的郵箱賬號和授權碼 client.Credentials = new NetworkCredential("18011389221@163.com", "授權碼"); //發送郵件 client.Send(message); Console.WriteLine("發送成功"); Console.ReadLine();
筆者只在自己給自己發郵件中測試成功過,在給別的郵箱中發郵件時總是被判定為垃圾郵件。如果讀者測試時並不能夠成功發送郵件,可按照如下幾部步驟檢查:
1.檢查客戶端授權碼是否開啟,授權碼是否停用
2.檢查是否開啟POP3/SMTP服務
3.將發件人添加到白名單中
4.取消智能收信分類
5.不要設置抄送人
從上面可以看出,在SMTP服務中網易郵箱比QQ郵箱的判斷要更加嚴格。
3.讀取郵件
讀取郵件要用到的協議為POP3協議。然而C#的類庫中,並沒有對POP3協議進行封裝。QQ郵箱在POP3協議的建立中,使用了SSL,這使得數據的傳輸更加的安全。然而網易郵箱並沒有使用SSL協議。
如果是電腦客戶端通過CMD命令與POP服務器建立鏈接的話,網易郵箱的操作(telnet)沒什么難度。但是QQ郵箱的操作(openssl)就相對比較復雜了,在使用openssl命令與主機建立連接時,必需傳入證書。C#對SSL已經有過包裝,通過C#可以輕松的與QQ郵箱和網易郵箱POP協議主機建立連接。
在開始之前,讀者可能需要先了解一些POP3協議的知識,關於POP3文檔讀者可以自行度娘。這里筆者列舉出,POP3協議中的命令碼:
命令 | 描述 |
USER [username] | 用戶名 |
PASS [password] | 密碼 |
APOP [Name,Digest] | 認可Digest是MD5消息摘要 |
STAT | 處理請求服務器發回關於郵箱的統計資料,如郵件總數和總字節數 |
UIDL [Msg#] | 處理返回郵件的唯一標識符,POP3會話的每個標識符都將是唯一的 |
LIST [Msg#] | 處理返回郵件數量和每個郵件的大小 |
RETR [Msg#] | 處理返回由參數標識的郵件的全部文本 |
DELE [Msg#] | 處理服務器將由參數標識的郵件標記為刪除,由quit命令執行 |
RSET | 處理服務器將重置所有標記為刪除的郵件,用於撤消DELE命令 |
TOP [Msg# n] | 處理服務器將返回由參數標識的郵件前n行內容,n必須是正整數 |
NOOP | 處理服務器返回一個肯定的響應 |
QUIT | 終止會話 |
接下來筆者連接QQ郵箱POP服務主機,展示一些常見的命令使用:
TcpClient clientSocket = new TcpClient(); clientSocket.Connect("pop.qq.com", 995);//連接到QQ郵箱POP服務器 //建立SSL連接 SslStream stream = new SslStream( clientSocket.GetStream(), false, (object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors) => { return true;//接收所有的遠程SSL鏈接 }); stream.AuthenticateAsClient("pop.qq.com");//驗證 //得到輸入流 StreamReader reader = new StreamReader(stream, Encoding.Default, true); //得到輸出流 StreamWriter writer = new StreamWriter(stream); Console.WriteLine(reader.ReadLine());//以+Ok開頭,表示連接成功 writer.WriteLine("USER 2965372061@qq.com"); writer.Flush(); Console.WriteLine(reader.ReadLine());//+Ok 表示用戶名正確 writer.WriteLine("PASS 授權碼"); writer.Flush(); Console.WriteLine(reader.ReadLine());//+Ok 表示密碼正確 writer.WriteLine("STAT"); writer.Flush(); Console.WriteLine(reader.ReadLine());//獲得郵件數 +OK 189 1058197 表示 189封郵件,1058197b writer.WriteLine("RETR 1"); writer.Flush(); String result = null;//獲得第1封郵件的內容,讀取的內容需要使用base64解碼 while ((result = reader.ReadLine()) != null) { Console.WriteLine(reader.ReadLine()); } Console.ReadLine();
讀者也可以測試連接網易郵箱POP服務器,
1.網易郵箱POP服務器的遠程地址是:pop.163.com:995。
2.無需建立SSL鏈接