網站首頁 編程語言 正文
前面寫了一篇通過smtp協議利用qq郵箱去實現發送郵件的功能。這一篇我們使用pop協議來實現一下接收郵件。
由于郵件的內容類型比較豐富,我暫時沒有一個比較好的解決方案(確切的說我是懶得一種種去解析),所以這里就獲取下郵件的列表,以及郵件的標題信息
實現功能
C#獲取QQ郵箱內的郵件
開發環境
開發工具: Visual Studio 2013
.NET Framework版本:4.5
實現代碼
static class Program
{
static string mail = "", pwd = "";
static void Main(string[] args)
{
Connect();
Console.WriteLine("結束運行");
Console.ReadKey();
}
static void Connect()
{
TcpClient tcpClient = new TcpClient("pop.qq.com", 995);
Console.WriteLine("已建立連接");
SslStream sslStream = new SslStream(tcpClient.GetStream(), true);
sslStream.AuthenticateAsClient("pop.qq.com");
//發送郵箱賬號
sslStream.SendPop("user " + mail);
Console.WriteLine(sslStream.ReadString().msg);
//發送郵箱密碼
sslStream.SendPop("pass " + pwd);
Console.WriteLine(sslStream.ReadString().msg);
//獲取郵箱統計數據
sslStream.SendPop("stat");
Console.WriteLine(sslStream.ReadString().msg);
//獲取郵件數量和每個郵件的大小
sslStream.SendPop("list");
string listMsg = sslStream.ReadString().msg;
List<string> list = listMsg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
if (list.Count < 2)
{
Console.WriteLine("未獲取到郵件");
return;
}
list.RemoveAt(0);
list.RemoveAt(list.Count - 1);
for (int i = list.Count - 1; i > -1; i--)
{
string[] arr = list[i].Split(' ');
//獲取郵件前n行內容
sslStream.SendPop("top " + arr[0] + " 1");
Console.WriteLine(list[i]);
Console.WriteLine(GetHeader(sslStream.ReadString().msg));
Console.WriteLine();
Console.WriteLine();
}
//string id = Console.ReadLine();
//sslStream.SendPop("retr " + id);
//Console.WriteLine(GetContext(sslStream.ReadString().msg));
sslStream.Close();
tcpClient.Close();
}
/// <summary>
/// 解析郵件標題
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
static string GetHeader(string text)
{
List<string> list = text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
list.RemoveAt(0);
list.RemoveAt(list.Count - 1);
StringBuilder sb = new StringBuilder();
for (int i = 1; i < list.Count; i++)
{
if (list[i].StartsWith("Date: "))
{
sb.AppendLine("發送時間:" + list[i].Substring("Date: ".Length));
}
if (list[i].StartsWith("From: "))
{
string value = list[i].Substring("From: ".Length);
sb.AppendLine("發送人:" + GetText(value));
}
if (list[i].StartsWith("Subject: "))
{
string value = list[i].Substring("Subject: ".Length);
sb.AppendLine("郵件標題:" + GetText(value));
}
if (list[i].StartsWith("Cc: "))
{
string value = list[i].Substring("Cc: ".Length);
sb.AppendLine("抄送:" + GetText(value));
}
}
return sb.ToString();
}
/// <summary>
/// 解析郵件內容
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
static string GetContext(string text)
{
List<string> list = text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
list.RemoveAt(0);
list.RemoveAt(list.Count - 1);
StringBuilder sb = new StringBuilder();
string s = list.Where(a => a.StartsWith("Content-Transfer-Encoding:")).SingleOrDefault();
int index = list.IndexOf(s) + 1;
for (int i = index; i < list.Count - index; i++)
{
sb.AppendLine(GetText(list[i]));
}
return sb.ToString();
}
/// <summary>
/// 解析原始文本
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
static string GetText(string value)
{
string encoding = "utf-8";
if (value.IndexOf("=?") == 0)
{
string tag = "";
if (value.Contains("?B?"))
{
tag = "?B?";
encoding = value.SubStr("=?", tag);
}
if (value.Contains("?b?"))
{
tag = "?b?";
encoding = value.SubStr("=?", tag);
}
if (value.Contains("?Q?"))
{
tag = "?Q?";
encoding = value.SubStr("=?", tag);
}
if (tag != "")
{
string last = "";
int lastIndex = value.LastIndexOf("?=");
if (lastIndex != value.TrimEnd().Length - 2)
{
last = value.Substring(lastIndex + 2);
}
string text = value.SubStr(tag, "?=");
if (tag.ToLower().Contains("b"))
{
return Encoding.GetEncoding(encoding).GetString(Convert.FromBase64String(text)) + last;
}
else if (tag.ToLower().Contains("q"))
{
return DecodeQP(text, encoding) + last;
}
}
}
return value;
}
static string SubStr(this string text, string start, string end)
{
try
{
int s = text.IndexOf(start);
int e = text.LastIndexOf(end);
if (s == -1 || e == -1)
{
return text;
}
string result = text.Substring(s + start.Length, e - s - start.Length);
return result;
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 發送數據到pop
/// </summary>
/// <param name="sslStream"></param>
/// <param name="text"></param>
/// <param name="isNewLine"></param>
static void SendPop(this SslStream sslStream, string text, bool isNewLine = true)
{
if (isNewLine)
{
text += "\r\n";
}
sslStream.Write(Encoding.ASCII.GetBytes(text));
}
static dynamic ReadString(this SslStream sslStream)
{
try
{
byte[] buffer = new byte[2048 * 2048];
int len = sslStream.Read(buffer, 0, buffer.Length);
string result = Encoding.UTF8.GetString(buffer, 0, len);
if (result.StartsWith("-ERR"))
{
throw new Exception(result);
}
else
{
return new { code = 1, msg = result };
}
}
catch (Exception ex)
{
return new { code = 0, msg = "讀取錯誤:" + ex.Message };
}
}
//Quoted-Printable 解碼(QP解碼)
static string DecodeQP(string data, string encoding)
{
char ch;
string ret = "";
byte[] bytes = new byte[data.Length];
int bIdex = 0;
try
{
for (int rIndex = 0; rIndex < data.Length; rIndex++)
{
ch = data[rIndex];
if (ch == '=')
{
rIndex++;
if (rIndex < data.Length && (Char.IsDigit(data[rIndex]) || Char.IsLetter(data[rIndex])))
{
bytes[bIdex++] = Byte.Parse(data.Substring(rIndex++, 2), System.Globalization.NumberStyles.HexNumber);
continue;
}
if (rIndex < data.Length && data[rIndex] == '\r' && (rIndex + 1) < data.Length && data[rIndex + 1] == '\n')
{
rIndex++;
continue;
}
}
if (ch == '\r' || ch == '\n')
continue;
bytes[bIdex++] = (byte)ch;
}
ret = Encoding.GetEncoding(encoding).GetString(bytes, 0, bIdex);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return ret;
}
}
原文鏈接:https://blog.csdn.net/qq_27410185/article/details/125641639
相關推薦
- 2024-03-10 【Redis】Redis哨兵模式
- 2022-03-22 nginx中一個請求的count計數跟蹤淺析_nginx
- 2022-05-20 ElasticSearch 7.X系列之:細節問題
- 2022-11-17 C#?函數返回多個值的方法詳情_C#教程
- 2023-04-02 go?MethodByName()不能獲取私有方法的解決_Golang
- 2023-03-19 Android全面屏適配與判斷超詳細講解_Android
- 2022-05-16 淺談react?16.8版本新特性以及對react開發的影響_React
- 2022-05-21 Ingress七層路由機制實現域名的方式訪問k8s_服務器其它
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支