添加邮件实体
/// <summary> /// 收到的邮件实体 /// </summary> public class MailInfo { /// <summary> /// 发件地址 /// </summary> public string From { get; set; } /// <summary> /// 收件地址 /// </summary> public string To { get; set; } /// <summary> /// 发件日期 /// </summary> public DateTime Date { get; set; } /// <summary> /// 内容 /// </summary> public string Content { get; set; } }
Pop3协议使用的是110端口,使用pop3连接邮件服务器首先要用TcpClient与邮件服务器建议一个连接,向流中写命令,然后可读取流中邮件服务器写入的返回信息。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Net; using System.Net.Sockets; namespace Email.Pop3 { /// <summary> /// 读取邮件客户端 /// </summary> public class Pop3Client { private TcpClient Server; private NetworkStream NetStrm; private StreamReader RdStrm; private string Data; private byte[] szData; private string CRLF = "\r\n"; /// <summary> /// 收件箱中邮件数量 /// </summary> private int mailCount; private bool conn = false; /// <summary> /// 是否已连接 /// </summary> public bool Connected { get { return conn; } } //// <summary> /// 连接邮件服务器 /// </summary> /// <param name="server">邮件服务器</param> /// <param name="account">账号</param> /// <param name="passWord">密码</param> /// <returns>是否连接成功</returns> public bool Connect(string server, string account, string passWord) { //用110端口新建POP3服务器连接 Server = new TcpClient(server, 110); try { //初始化 NetStrm = Server.GetStream(); RdStrm = new StreamReader(Server.GetStream()); string init = RdStrm.ReadLine(); //登录服务器过程 Data = "USER " + account + CRLF; szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray()); NetStrm.Write(szData, 0, szData.Length); string user = RdStrm.ReadLine(); Data = "PASS " + passWord + CRLF; szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray()); NetStrm.Write(szData, 0, szData.Length); string pass = RdStrm.ReadLine(); if (pass[0] == '+') { //向服务器发送STAT命令,从而取得邮箱的相关信息:邮件数量和大小 Data = "STAT" + CRLF; szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray()); NetStrm.Write(szData, 0, szData.Length); //依据返回信息,初始化队列大小 string[] inboxParams = RdStrm.ReadLine().Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); int.TryParse(inboxParams[1], out mailCount); conn = true; } } catch (InvalidOperationException ex) { conn = false; throw ex; } return conn; } /// <summary> /// 断开连接 /// </summary> public void DisConnect() { //向服务器发送QUIT命令从而结束和POP3服务器的会话 Data = "QUIT" + CRLF; szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray()); NetStrm.Write(szData, 0, szData.Length); string msg = RdStrm.ReadLine(); //断开连接 NetStrm.Close(); RdStrm.Close(); } /// <summary> /// 收信 /// </summary> /// <returns></returns> public Queue<MailInfo> Receive() { Queue<MailInfo> mailQueue = new Queue<MailInfo>(); string szTemp; for (int i = 1; i <= mailCount; i++) { //根据邮件编号从服务器获得相应邮件 Data = "RETR " + i + CRLF; szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray()); NetStrm.Write(szData, 0, szData.Length); szTemp = RdStrm.ReadLine(); StringBuilder mailTxt = new StringBuilder(); if (szTemp.Length > 0 && szTemp[0] != '-') { //不断地读取邮件内容,直到结束标志:英文句号 while (szTemp != ".") { mailTxt.Append(szTemp + "\n"); szTemp = RdStrm.ReadLine(); } MailInfo m = new MailInfo() { From = MessageParse.GetFrom(mailTxt.ToString()), To = MessageParse.GetTo(mailTxt.ToString()), Date = MessageParse.GetDate(mailTxt.ToString()), Content = MessageParse.GetContent(mailTxt.ToString()) }; mailQueue.Enqueue(m); } } return mailQueue; } /// <summary> /// 删除读取后的邮件 /// </summary> public void Delete() { for (int i = 1; i <= mailCount; i++) { Data = "DELE " + i + CRLF; szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray()); NetStrm.Write(szData, 0, szData.Length); } } } }
读取邮件的标题、内容等需要解析。下面是一个提取邮件标题、内容、发件箱等的解析类。不太完整,仅供参考。
/// <summary> /// 读取邮件内容 /// </summary> public class MessageParse { /// <summary> /// 获取发件人 /// </summary> /// <param name="message"></param> /// <returns></returns> public static string GetFrom(string message) { if (!message.Contains("\nFrom:")) { return string.Empty; } string cutMsg = message.Substring(message.IndexOf("\nFrom:") + 7); cutMsg = cutMsg.Remove(cutMsg.IndexOf("\n")); if (cutMsg.Contains('<') && cutMsg.Contains('>')) { int indexS = cutMsg.IndexOf('<'); int indexE = cutMsg.IndexOf('>'); if (indexE - 1 > indexS) { cutMsg = cutMsg.Substring(indexS + 1, indexE - indexS - 1); } } cutMsg=cutMsg.Trim('>'); cutMsg=cutMsg.Trim('<'); return cutMsg; } /// <summary> /// 获取收件人 /// </summary> /// <param name="message"></param> /// <returns></returns> public static string GetTo(string message) { if (!message.Contains("\nTo:")) { return string.Empty; } string cutMsg = message.Substring(message.IndexOf("\nTo:") + 5); cutMsg = cutMsg.Remove(cutMsg.IndexOf("\n")); if (cutMsg.Contains('<') && cutMsg.Contains('>')) { int indexS = cutMsg.IndexOf('<'); int indexE = cutMsg.IndexOf('>'); if (indexE - 1 > indexS) { cutMsg = cutMsg.Substring(indexS + 1, indexE - indexS - 1); } } cutMsg=cutMsg.Trim('>'); cutMsg=cutMsg.Trim('<'); return cutMsg; } /// <summary> /// 获取收件日期 /// </summary> /// <param name="message"></param> /// <returns></returns> public static DateTime GetDate(string message) { if (!message.Contains("\nTo:")) { return DateTime.MinValue; } string cutMsg = message.Substring(message.IndexOf("\nDate:") + 7); cutMsg = cutMsg.Remove(cutMsg.IndexOf("\n")); DateTime time = DateTime.Now; try { time = Convert.ToDateTime(cutMsg); } catch { } return time; } /// <summary> /// 获取内容 /// </summary> /// <param name="message"></param> /// <returns></returns> public static string GetContent(string message) { if (!message.Contains("\nContent")) { return string.Empty; } string cutMsg = message.Substring(message.LastIndexOf("\nContent")); cutMsg = cutMsg.Substring(cutMsg.IndexOf("\n\n") + 2); if (cutMsg.IndexOf("\n\n") > 0) { cutMsg = cutMsg.Remove(cutMsg.IndexOf("\n\n")); } if (message.Contains("\nContent-Transfer-Encoding: base64")) { if (message.Contains("charset=")) { string charSet = message.Substring(message.LastIndexOf("charset=") + 8); charSet = charSet.Remove(charSet.IndexOf('\n')).Trim('"'); try { Encoding encoding = Encoding.GetEncoding(charSet); cutMsg = Encoding.GetEncoding(charSet).GetString(Convert.FromBase64String(cutMsg)); } catch { try { cutMsg = Encoding.Default.GetString(Convert.FromBase64String(cutMsg)); } catch { } } } } return cutMsg; } }