2009年5月2日 星期六

POP3的基本作業(Basic Operation)提到了幾個基本的操作;而事實上這幾個操作都包含在POP3 == RFC 1939一文中所提到的POP3Client類別(Class)裡。這個類別原來是用C#(C Sharp)寫的,最近亞伯特把它整理了一下,同時也改寫成VB以及VC++以供參考。 連接POP3伺服器函數(Function) Connect() 這個函數使用型別為TcpClient的物件(tcClient)來連接POP3伺服器;在連接的同時,這個函數會建立一個型別為NetwrokStream的物件(nsStream),這個物件用夾提供網路存取資料的功能;呼叫它時,必須提供伺服器稱(例如HiNet的郵件伺服器,ms1.hinet.net)以及埠號(按照POP3,通常是110)。函數在結束時呼叫函數GetResponse(),這個函數負責透過nsStream讀取伺服器回應的訊息,並且判斷連結是否成功: [VB 的程式碼] Public Function Connect(ByVal Server As String, ByVal Port As Integer) As Boolean '--- 連接伺服器/Connect to POP3 server ------------------------------     Try     tcClient = New TcpClient(Server, Port)     nsStream = tcClient.GetStream()     nsStream.ReadTimeout = 15000     Catch         Throw     End Try     Return GetResponse() End Function [VC#的程式碼] public bool Connect(string Server, int Port) {     //--- 連接伺服器/Connect to POP3 server ------------------------------     try     {         tcPOP3Client = new TcpClient(Server, Port);         nsStream = tcPOP3Client.GetStream();         nsStream.ReadTimeout = 15000;     }     catch (SocketException)     {         throw;     }     return GetResponse(); } [VC++的程式碼] bool CPOP3Client::Connect(String^ Server, int Port) { //--- 連接伺服器/Connect to POP3 server ------------------------------     try     {         tcPOP3Client = gcnew TcpClient(Server, Port);         nsStream = tcPOP3Client->GetStream();         nsStream->ReadTimeout = 15000;     }     catch (...)     {         throw;     }     return GetResponse(); } 登錄POP3伺服器函數Logon() 它藉著呼叫函數Request()執行登錄的動作 ;Request函數是透過nsStream把要求傳給伺服器,然後呼叫GetResponse()函數取得回應的訊息,並且藉由該訊息判斷是否登錄成功: [VB 的程式碼] Public Function Logon(ByVal Username As String, ByVal Password As String) As Boolean '--- 登錄郵件伺服器/Logon POP3 server -------------------------------- '     Return Request("USER", Username) And Request("PASS", Password) End Function [VC#的程式碼]  public bool Logon(string UserName, string Password) { //--- 登錄郵件伺服器/Logon POP3 server --------------------------------     return Request("USER", UserName) && Request("PASS", Password); } [VC++的程式碼] bool CPOP3Client::Logon(String^ UserName, String^ Password) { //--- 登錄郵件伺服器/Logon POP3 server --------------------------------     return Request("USER", UserName) && Request("PASS", Password); } [VB 的程式碼] Private Function Request(ByVal Command As String) '--- 傳送指令給伺服器/Request POP3Server -----------------------------     Dim bytCommand() As Byte = Encoding.ASCII.GetBytes(Command & vbCrLf)     nsStream.Write(bytCommand, 0, bytCommand.Length)     Return GetResponse() End Function [VC#的程式碼]  private bool Request(string Command) { //--- 傳送指令給伺服器/Request POP3Server -----------------------------     Byte[] bytCommand;     bytCommand = Encoding.ASCII.GetBytes(Command + "\r\n");     nsStream.Write(bytCommand, 0, bytCommand.Length);     return GetResponse(); } [VC++的程式碼] bool CPOP3Client::Request(String^ Command) { //--- 傳送指令給伺服器/Request POP3Server -----------------------------     array<Byte>^ bytCommand;     bytCommand =Encoding::ASCII->GetBytes(Command + "\r\n");     nsStream->Write(bytCommand, 0, bytCommand->Length);     return GetResponse(); } 讀取伺服器回應訊息的函數GetResponse() 如前所述,GetResponse()是透過nsStream讀取伺服器的回應訊息;所以GetResponse()不但要正確的取得伺服器的回應,而且要判斷該訊息是成功(+OK)的訊息或者是失敗(-ERR)的訊息。 [VB 的程式碼] Public Function GetResponse() As Boolean '--- 讀取伺服器回應的資料/Get response from POP3 server --------------- Dim iBytes As Integer Dim bOk As Boolean     Try         '--- 讀取資料/Getting Data --------------------------------------         iBytes = nsStream.Read(bytData, 0, bytData.Length)         strResponse = Encoding.ASCII.GetString(bytData, 0, iBytes)         bOk = strResponse.StartsWith("+OK")         '--- 多行的處理/For multi-line -----------------------------------         If (strResponse.IndexOf(vbCrLf) < (iBytes - 2)) Then             Do While Not (strResponse.EndsWith("." & vbCrLf))                 iBytes = nsStream.Read(bytData, 0, bytData.Length)                 strResponse &= Encoding.ASCII.GetString(bytData, 0, iBytes)             Loop             strResponse = strResponse.Substring(0, strResponse.Length - 3)             strResponse = Unfolding(strResponse)         End If         If bOk Then strResponse = strResponse.Substring(3) _                                         Else strResponse.Substring(4)         strResponse = strResponse.TrimStart()     Catch         bOk = False     End Try     Return bOk End Function [VC#的程式碼]  private bool GetResponse() { //--- 讀取伺服器回應的資料/Get response from POP3 server ---------------     int iBytes;     bool bOK = false;     try     {         //--- 讀取資料/Getting Data --------------------------------------         iBytes = nsStream.Read(bytData, 0, bytData.Length);         strResponse = Encoding.ASCII.GetString(bytData, 0, iBytes);         bOK = strResponse.StartsWith("+OK");         //--- 多行的處理/For multi-line -----------------------------------         if ((strResponse.IndexOf("\r\n") < (iBytes - 2)))         {             while (!strResponse.EndsWith(".\r\n"))             {                 iBytes = nsStream.Read(bytData, 0, bytData.Length);                 strResponse += Encoding.ASCII.GetString(bytData, 0, iBytes);             }             strResponse = strResponse.Substring(0, strResponse.Length - 3);             strResponse = Unfolding(strResponse);         }         if (bOK) strResponse = strResponse.Substring(3);         else strResponse.Substring(4);         strResponse = strResponse.TrimStart();     }     catch (IOException)     {         bOK = false;     }     return bOK; } [VC++的程式碼] bool CPOP3Client::GetResponse() { //--- 讀取伺服器回應的資料/Get response from POP3 server ---------------     int iBytes;     bool bOK = false;     try     {         //--- 讀取資料/Getting Data --------------------------------------         iBytes = nsStream->Read(bytData, 0, bytData->Length);         strResponse = Encoding::ASCII->GetString(bytData, 0, iBytes);         bOK = strResponse->StartsWith("+OK");         //--- 多行的處理/For multi-line -----------------------------------         if ((strResponse->IndexOf("\r\n") < (iBytes - 2)))         {             while (!strResponse->EndsWith(".\r\n"))             {                 iBytes = nsStream->Read(bytData, 0, bytData->Length);                 strResponse += Encoding::ASCII->GetString(bytData, 0, iBytes);             }             strResponse = strResponse->Substring(0, strResponse->Length - 3);             strResponse = Unfolding(strResponse);         }         strResponse=bOK?strResponse->Substring(3):strResponse->Substring(4);         strResponse=strResponse->TrimStart();     }     catch (...)     {         bOK = false;     }     return bOK; }  

沒有留言: