紧接着上文的介绍,本文具体通过一个例子来描述如何通过C#来实现POP3协议的全过程,考虑到简洁性,本例子中将错误处理均忽略掉了,大家在引用这个例子代码的时候特别要注意到添加错误处理,增加程序的健壮性:
首先是Main函数实现:
classProgram
{
staticvoid Main(string[] args)
{
Pop3Sample sample = newPop3Sample();
if (sample.InitializeSocket())
{
sample.Pop3SessionSample();
sample.UninitializeSocket();
}
}
}
然后是实现POP3协议类:
classPop3Sample
{
privatestring m_strServer = null;
privatestring m_strUserName = null;
privatestring m_strPassword = null;
privateTcpClient m_tcpClient = null;
public Pop3Sample()
{
m_strServer = "pop3.163.com";
m_strUserName = "xxx";
m_strPassword = "yyy";
}
publicbool InitializeSocket()
{
bool successFlag = false;
m_tcpClient = newTcpClient(AddressFamily.InterNetwork);
try
{
m_tcpClient.Connect(m_strServer, 110);
successFlag = true;
}
catch (Exception ex)
{
m_tcpClient = null;
System.Diagnostics.Debug.WriteLine(ex.Message);
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
return successFlag;
}
publicvoid UninitializeSocket()
{
if (m_tcpClient != null)
{
m_tcpClient.Close();
}
}
publicvoid Pop3SessionSample()
{
//S: +OK POP3 server ready
//C: USER xxx
//S: PASS yyyy
//C: STAT
//S: +OK 2 320
//C: LIST
//S: +OK 2 messages (320 octets)
//S: 1 120
//S: 2 200
//S: .
//C: RETR 1
//S: +OK 120 octets
//S: <the POP3 server sends message 1>
//S: .
//C: DELE 1
//S: +OK message 1 deleted
//C: RETR 2
//S: +OK 200 octets
//S: <the POP3 server sends message 2>
//S: .
//C: DELE 2
//S: +OK message 2 deleted
//C: QUIT
//S: +OK dewey POP3 server signing off (maildrop empty)
//C: <close connection>
string response = PrintResponseLine(); //wait for server side's connection confirm message
//string secretString = this.GetLastToken(response);
//string md5Code = GetCompoundMD5Digest(secretString, m_strPassword);
//string cmdString = "APOP " + m_strUserName + " " + md5Code;
//SendCommandLine(cmdString);
//PrintResponseLine(); //wait for authentication OK message
string cmdString = "User " + m_strUserName;
SendCommandLine(cmdString);
cmdString = "Pass " + m_strPassword;
SendCommandLine(cmdString);
PrintResponseLine(); //wait for authentication OK message
SendCommandLine("STAT");
PrintResponseLine();
SendCommandLine("LIST");
string listResponse = PrintResponseLine();
int totalMails = this.GetMailCount(listResponse);
if (totalMails == 0)
{
System.Diagnostics.Debug.WriteLine("No more new mails.");
}
else
{
for (int i = 1; i <= totalMails; i++)
{
System.Diagnostics.Debug.WriteLine("--------------------------------------------------");
SendCommandLine("RETR " + Convert.ToString(i));
string mail_header = PrintResponseLine();
string mail_content = PrintResponseLine();
System.Diagnostics.Debug.WriteLine("**********Email " +Convert.ToString(i) + " length:" + mail_content.Length);
}
}
SendCommandLine("QUIT");
PrintResponseLine();
System.Diagnostics.Debug.WriteLine("------------------------------------------");
}
privatevoid SendCommandLine(string commandLine)
{
NetworkStream ns = this.m_tcpClient.GetStream();
string email = commandLine + "\r\n";
byte[] emailBytes = Encoding.ASCII.GetBytes(email);
ns.Write(emailBytes, 0, emailBytes.Length);
System.Diagnostics.Debug.WriteLine(email);
}
privatestring PrintResponseLine()
{
StringBuilder sb = newStringBuilder(4096);
NetworkStream ns = this.m_tcpClient.GetStream();
byte[] byteBuffer = newbyte[4096];
do
{
int read_size = ns.Read(byteBuffer, 0, 4096);
string email = Encoding.ASCII.GetString(byteBuffer, 0, read_size);
sb.Append(email);
System.Diagnostics.Debug.WriteLine(email);
} while (ns.DataAvailable);
return sb.ToString();
}
privateint GetMailCount(string response)
{
int totalMails = 0;
string [] tokens = response.Split(newstring[]{" "},StringSplitOptions.RemoveEmptyEntries);
if (tokens.Length > 2)
{
totalMails = Convert.ToInt32(tokens[1]);
}
return totalMails;
}
privatestring GetLastToken(string response)
{
string [] tokens = response.Split(newstring[]{" "},StringSplitOptions.RemoveEmptyEntries);
return tokens[tokens.Length-1];
}
privatestring GetCompoundMD5Digest(string secretString, string password)
{
StringBuilder sb = newStringBuilder(64);
sb.Append(secretString).Append(password);
string wholeSecret = sb.ToString();
return ToMD5Hex(wholeSecret);
}
publicstring ToMD5Hex(string strInput)
{
// step 1, calculate MD5 hash from input
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(strInput);
byte[] hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
StringBuilder sb = newStringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
}
对于最后读出来的Mail具体内容,大家还需要通过MIME协议进行解析整体的内容,具体的解析过程留给大家自己去做了,不是本文的讲解重点。