在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;
}