一個POP3客戶端的C#類 (轉)
一個POP3客戶端的類:namespace prefix = o ns = "urn:schemas--com::office" />
作者: ?id=28276">Bill Dean
關鍵詞: C#, ,.NET, INTERNET
提交: 2002-02-26
: -08-06
摘要: 本文描述的是一個實現了標準POP3命令的C#類。
· /pop3client/pop3client.zip">源 - 2 Kb
· - 5 Kb
·
執行結果 hspace=0 src="/Develop/ArticleImages/20/20575/CSDN_Dev_Image_2003-8-211342380.jpg" align=baseline border=0>
簡介
讀完Agus Kurniawan關於用C#與POP3通訊的,我決定如果建立一個POP3客戶端的類的話,我將走得更遠。我決定為每一個標準的POP3命令實現方法,每一個方法返回一個包含(相應的)POP3伺服器響應的字串,某些情況命令無效,那麼這些方法檢查這些錯誤並且返回一個錯誤資訊而不是直接傳送命令到伺服器。隨文的原始檔包含類的定義和一個使用該類與POP3伺服器通訊的控制檯演示程式(前面列出)。
類,方法和屬性
隨附的包含一個類: POP3Client
。
POP3Client
類包含十個公用方法,其中九個代表標準的
POP3
命令:
· DELE,
· LIST,
· N,
· PASS,
· QUIT,
· RETR,
· RSET,
· STAT
· and USER
每一個"POPmethods"返回一個字串,內容為(相應的)POP3伺服器響應結果,或者不恰當的命令導致的錯誤資訊。最後一個公用方法:connect
用來初始化連結。沒有實現可選的POP3命令:APOP, TOP and UIDL。
開始工作後不久,我認識到所有POP3方法應該按以下四個基本步驟實現:
1. 檢查該命令載當前的POP狀態中是否有效。
2. 如果有效,傳送命令到伺服器。
3. 讀取響應結果。
4. (如果需要)改變POP狀態。
我決定用一個叫state的屬性來跟蹤POP會話的當前狀態,資料型別宣告為connect_state的列舉型別。你們可以看到這些宣告在類的定義的頂部。
public enum connect_state {disc,AUTHORIZATION,TRANSACTION,UPDATE};
...
public connect_state state=connect_state.disc ;
有三個POP狀態:AUTHORIZATION
、TRANSACTION
、
UPDATE
。(完整的
POP3
定義請參見
.cmu.edu//rfc1725.html">RFC 1725)state屬性在建立任何與POP3伺服器的連線之前被設為disc(斷開),建立連線後變為AUTHORIZATION。
I also thought it would be useful to store the user name, pass, pop server name and error state (i.e.: did an error occur on the last POP3 command), so I add these properties to the class:
我也認為儲存名、密碼、POP3伺服器名和錯誤狀態是有用的(例如:判斷上一個POP3命令是否發生錯誤),所以我在類中加入了這些屬性:
public string user;
public string pwd;
public string pop;
public bool error;
連線伺服器(TcpClient)、傳送(NetworkStream)和接收資料(StreamReader)的機制直接取自Agus的程式碼。我甚至保留了相同的變數名:
// 借用自 Agus Kurniawan的文章:"Retrieve From a POP3 Server Using C#"
// at
private TcpClient Server;
private NetworkStream NetStrm;
private StreamReader RdStrm;
private string Data;
private byte[] szData;
private string CRLF = "rn";
在做任何其他工作之前,我們需要建立道伺服器的連線以及取得流中的資訊。這個在connect
公用方法中進行。
public string connect()
{
// 初始化連線,這段程式碼是稍作修改“借” 來的
//來自Agus Kurniawan在的文章
// "Retrieve Mail From a POP3 Server Using C#"
// at
// 用110埠建立伺服器
Server = new TcpClient(pop,110);
try
{
// 初始化
NetSt= Server.GetStream();
RdStrm= new StreamReader(Server.GetStream());
//POP會話現在被設為AUTHORIZATION狀態
state=connect_state.AUTHORIZATION ;
return(RdStrm.ReadLine ());
}
catch(InvalidOperationException err)
{
return("Error: "+err.ToString());
}
}
注意:只要連線一初始化,會話就進入了AUTHORIZATION狀態。
正如前面所提到的,九個POP3方法實質上具有相同的結構。DELE
方法的原始碼展示出該結構。
public string DELE(int msg_number)
{
string temp;
if (state != connect_state.TRANSACTION )
{
// 只有在POP會話處於TRANSACTION狀態時 DELE 命令才為有效
temp="Connection state not = TRANSACTION";
}
else
{
issue_command("DELE " + msg_number.ToString ());
temp=read_single_line_response();
}
return(temp);
}
首先,我們知道DELE
POP3命令只在TRANSACTION
狀態有效,所以如果該類不在這個狀態,檢視記錄在state
屬性的值,那麼返回一個錯誤資訊而不是傳送請求到POP3伺服器。當處於別的狀態時傳送DELE
命令也不會損傷POP3伺服器,只是會產生內部的錯誤資訊而已。如果你寧可讓POP3伺服器產生狀態的錯誤資訊,儘可移出if結構只留下issue_command()
。一旦確定POP會話處於正確的狀態,我們就使用私有方法issue_command
傳送"DELE
"命令到伺服器。描述了DELE命令返回一個從伺服器發回的單行響應,我們用方法read_single_line_response
來讀取。兩個方法都相當直接明瞭,不管是向建立連結的伺服器寫字元還是從建立連結的伺服器讀取來自於網路流的字元。因為執行完DELE命令後POP會話狀態仍為TRANSACTION狀態,我們沒必要擔心要改變state
值。state
改變的例子請參見原始碼的PASS
方法。
private void issue_command(string command)
{
// 傳送命令到POP伺服器,這段程式碼是稍作修改“借” 來的
// 來自Agus Kurniawan在的文章
// "Retrieve Mail From a POP3 Server Using C#"
//
Data= command + CRLF;
szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray());
NetStrm.Write(szData,0,szData.Length);
}
private string read_single_line_response()
{
// 讀取POP伺服器的響應結果,這段程式碼是稍作修改“借” 來的
// 來自Agus Kurniawan在的文章
// "Retrieve Mail From a POP3 Server Using C#"
//
string temp;
try
{
temp = RdStrm.ReadLine();
was_pop_error(temp);
return(temp);
}
catch(InvalidOperationException err)
{
return("Error in read_single_line_response(): " + err.ToString ()) ;
}
}
注意,在某些情況,有些POP3命令返回多行響應。這裡也採用一個名叫read_multi_line_response
的方法來處理。我前面已經提到過,我認為顯示地判斷最後一個POP命令是否正確執行,或者POP3伺服器是否返回錯誤,將是有用的。這裡用was_pop_error
私有方法來檢查。
private void was_pop_error(string response)
{
// 檢查POP伺服器發出了響應並認為發生了錯誤
if(response.StartsWith ("-"))
{
// 如果第一個字元是"-"
// 那麼pop伺服器在執行客戶端發過去的最後一個命令時發生錯誤
error=true;
}
else
{
// 成功
error=false;
}
}
使用示例
POP3協議的細節有點超出本文章的範圍。所以如果你想多瞭解POP3的話,我建議你去RFC 1725,你可以在找到。讓我們簡單的看一下示例程式,以便了解怎樣使用這個類:
static void Main(string[] args)
{
POP3Client.POP3client Demo = new POP3Client.POP3client();
Console.WriteLine ("****connecting to server:");
Console.WriteLine (Demo.connect ("your_pop3_server"));
Console.WriteLine ("****Issuing USER");
Console.WriteLine (Demo.USER ("user_id"));
Console.WriteLine ("****Issuing PASS");
Console.WriteLine (Demo.PASS ("password"));
Console.WriteLine ("****Issuing STAT");
Console.WriteLine (Demo.STAT () );
Console.WriteLine ("****Issuing LIST");
Console.WriteLine (Demo.LIST () );
Console.WriteLine ("****Issuing RETR 700...this will cause the POP3 server to gack a "
+ "hairball since there is no message 700");
Console.WriteLine (Demo.RETR (700) );
// 如果沒有700訊息,將會導致POP3丟擲一個錯誤
Console.WriteLine ("****Issuing RETR 7");
Console.WriteLine (Demo.RETR (7) );
Console.WriteLine ("****Issuing QUIT");
Console.WriteLine (Demo.QUIT ());
Console.ReadLine ();
}
總之,你建立一個POP3Client
類的例項,用你的POP3伺服器呼叫connect
方法,就可以開始傳送命令了。你將需要呼叫USER
和PASS
方法以成功登陸伺服器,呼叫其他POP3方法之前必須取得有效的登陸資訊。
我希望你們部分人發覺這篇文章是有用的。我也希望收到反饋或建議。
請大家明白該程式碼沒有任何的保證,不管是明示還是暗示。該程式碼嚴格的“無保證”提供,僅僅為教育目的。誰使用誰負責。要使用該程式碼,請允諾使用該程式碼帶來的任何損失與作者和Restek無關。
歷史
- 2003-08-06 —— Ronny Reinertsen好意地把C#版本轉為VB.NET
參看原文:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-984457/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- c#實現redis客戶端(一)C#Redis客戶端
- C# MQTT客戶端C#MQQT客戶端
- FtpWebRequest類_ftp客戶端FTPWeb客戶端
- 客戶端和服務端(C#) 時間戳的生成和轉換客戶端服務端C#時間戳
- c# 獲取客戶端IPC#客戶端
- FishRedux完成一個玩安卓客戶端Redux安卓客戶端
- 手擼一個新聞客戶端客戶端
- 建立一個Twisted Reactor TCP客戶端ReactTCP客戶端
- Winform客戶端引用WCF客戶端後,部分類無法正常使用ORM客戶端
- C#版Nebula客戶端編譯C#客戶端編譯
- websocket(多個客戶端)Web客戶端
- 客戶端JavaScript的5個弊端客戶端JavaScript
- GankIo又一個ReactNative客戶端React客戶端
- cvs客戶端大全(轉)客戶端
- C#之使用CefSharp建立客戶端C#客戶端
- C# 判斷客戶端是否禁用Cookie的方法C#客戶端Cookie
- 一個克隆物件的C#基類 (轉)物件C#
- 一個高顏值Flutter版WanAndroid客戶端FlutterNaNAndroid客戶端
- 寫一個Flutter彩票客戶端--開獎列表Flutter客戶端
- React Native 專案(One 【一個】客戶端)React Native客戶端
- CXF入門教程(2) -- 第一個客戶端客戶端
- 自己動手寫一個能操作redis的客戶端Redis客戶端
- 一個支援Sora模型文字生成影片的Web客戶端Sora模型Web客戶端
- C#實現組播源及客戶端C#客戶端
- [轉載] 使用Redis的Java客戶端JedisRedisJava客戶端
- ETH官方客戶端Geth的使用(一)客戶端
- 聚聞 ~ 一個聚合資料新聞客戶端客戶端
- 常用的Redis客戶端的併發模型(轉)Redis客戶端模型
- ftp客戶端軟體,ftp客戶端軟體哪個好用,使用方法FTP客戶端
- 擼了一個可除錯 gRPC 的 GUI 客戶端除錯RPCGUI客戶端
- C# 客戶端程式呼叫外部程式的三種實現C#客戶端
- C#客戶端Redis伺服器的分散式快取C#客戶端Redis伺服器分散式快取
- C#不安裝Oracle客戶端執行程式的辦法C#Oracle客戶端行程
- 《samba搭建win客戶端和linux客戶端的區別》Samba客戶端Linux
- 客戶端Cookie中文程式設計 (轉)客戶端Cookie程式設計
- dubbo客戶端客戶端
- Pulsar客戶端客戶端
- mqtt 客戶端MQQT客戶端