一、 POP3协议简介
1、什么是POP3协议:
邮局协议(Post Office Protocol,简称POP)是TCP/IP协议族中的一员,由RFC 1939 定义。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。最新版本为POP3,全名“Post Office Protocol - Version 3”,而提供了SSL加密的POP3协议被称为POP3S。
2、POP3协议具体过程:
POP 协议支持“离线”邮件处理。其具体过程是:邮件发送到服务器上,电子邮件客户端调用邮件客户机程序以连接服务器,并下载所有未阅读的电子邮件。这种离线访问模式是一种存储转发服务,将邮件从邮件服务器端送到个人终端机器上,一般是PC机或 MAC。一旦邮件发送到 PC 机或MAC上,邮件服务器上的邮件将会被删除。但目前的POP3邮件服务器大都可以“只下载邮件,服务器端并不删除”,也就是改进的POP3协议。
3、电子邮件系统的基本网络结构
二、 运用C#实现POP3接收邮件的三种方法
1、 利用Socket组件
socket本质是编程接口,是对TCP/IP的封装。TCP/IP是传输层的协议。POP3是应用层的协议,是基于TCP/IP协议的。所以,使用socket实现上述几种协议的客户端,其实是对借助socket对TCP/IP数据传输的封装基础,再往上封装一层的。
POP3只需要建立一个连接,客户端向服务器发命令,服务器向客户端返回数据就行了。具体就是通过socket发命令,再通过socket接数据 。
具体实现如下图(实现代码不再详细阐述):
该POP3客户端主要实现的就是接收邮件功能了,然而并没有实现邮件内容解析功能。
并且在连接过程中,163、126、sina等邮箱均可以登录至相应的pop服务器,唯独QQ邮箱受阻,提示信息为:-err login fail a secure connection is required(such as ssl),所以需要建立ssl的相关安全连接才可以登录至pop服务器,因此放弃该方法,所以选择方法三。
2、 利用OpenPop组件
这是一款可以支持 SSL 收发邮件的控件,和LumiSoft组件类似,自己在使用LumiSoft之前对OpenPop组件进行了测试,其中邮件解析的各项数据较全。但是OpenSmtp组件连接不了ssl,这个只对pop协议适用,而LumiSoft对所有的邮件传输协议均适用,所以选择了方法三。
运行效果如下图:
3、 利用LumiSoft组件
LumiSoft.Net是非常强大的开源组件,不仅仅发送邮件,同样也可用于接收邮件,在这周的学习时间里是个人找到的最好的开源组件了。阅读LumiSoft.Net的源代码,可以看到LumiSoft.Net编程严格遵循了RFC(Request For Comments)定义的协议规范。通过阅读这些源码对于了解RFC和其中关于邮件网络协议规范也是非常有帮助的。
如果要查阅RFC文档可以通过LumiSoft组件链接网站查询。
运行效果如下图:
主界面:
解析:
三、 运用LumiSoft组件实现接收邮件
1、 运用的命名空间
using System
using System.Windows.Forms;
using System.IO;
using LumiSoft.Net;
using LumiSoft.Net.Mail;
using LumiSoft.Net.POP3.Client;
using LumiSoft.Net.MIME;
2、 连接并获取信息部分
(1)、连接到POP3服务器
POP3_Client.Connect函数主要是连接pop服务器,端口,是否用ssl
POP3_Client.Authenticate函数主要验证邮箱和邮箱授权码(通常为16位)
private void btn_connect_Click(object sender, EventArgs e)
{
if (txt_username.Text == "")
{
MessageBox.Show(this, "Please fill user name !", "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
POP3_Client pop3 = new POP3_Client();
try
{
pop3.Connect(txt_server.Text, (int)number_port.Value, cb_isSSL.Checked);
pop3.Authenticate(txt_username.Text, txt_password.Text, true);
m_pPop3 = pop3;
this.DialogResult = DialogResult.OK;
FillMessagesList();
}
catch (Exception x)
{
MessageBox.Show(this, "POP3 server returned: " + x.Message + " !", "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error);
pop3.Dispose();
}
}
(2)、获取邮件头信息函数FillMessagesList()
通过POP3_ClientMessage、Mail_Message获取信息,并写进ListViewItem的项内,然后传递给lst_message的Item,以达到在窗体中显示的目的。
private void FillMessagesList()
{
this.Cursor = Cursors.WaitCursor;
try
{
foreach (POP3_ClientMessage message in m_pPop3.Messages)
{
Mail_Message mime = Mail_Message.ParseFromByte(message.HeaderToByte());
Mail_Message mime2 = Mail_Message.ParseFromByte(message.MessageToByte());
ListViewItem item = new ListViewItem();
if (mime.From != null)
{
item.Text = mime.From.ToString();
}
else
{
item.Text = "<none>";
}
if (string.IsNullOrEmpty(mime.Subject))
{
item.SubItems.Add("<none>");
}
else
{
item.SubItems.Add(mime.Subject);
}
item.SubItems.Add(mime.Date.ToString());
item.SubItems.Add(((decimal)(message.Size / (decimal)1000)).ToString("f2") + " kb");
if (mime.Cc != null)
{
item.SubItems.Add(Convert.ToString(mime.Cc));
}
else
{
item.SubItems.Add("<none>");
}
if (mime.Bcc != null)
{
item.SubItems.Add(Convert.ToString(mime.Bcc));
}
else
{
item.SubItems.Add("<none>");
}
item.SubItems.Add(mime.ContentTransferEncoding);
item.SubItems.Add(mime.MessageID);
item.SubItems.Add(mime.MimeVersion);
item.SubItems.Add(Convert.ToString(mime.Received));
item.SubItems.Add(mime2.BodyHtmlText);
item.SubItems.Add(Convert.ToString(mime.ContentType));
item.SubItems.Add(Convert.ToString(mime.IsDisposed));
item.SubItems.Add(Convert.ToString(mime.IsModified));
item.Tag = message;
lst_messages.Items.Add(item);
}
}
catch (Exception x)
{
MessageBox.Show(this, "Error: " + x.Message, "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
this.Cursor = Cursors.Default;
}
(3)、SSL判断函数
通过WellKnownPorts方法自动获取各个邮件服务器所在ssl或者非ssl状态下对应的端口。
private void cb_isSSL_CheckedChanged_1(object sender, EventArgs e)
{
if (cb_isSSL.Checked)
{
number_port.Value = WellKnownPorts.POP3_SSL;
}
else
{
number_port.Value = WellKnownPorts.POP3;
}
}
3、 通过窗体获取具体解析的信息部分
(1)、邮件列表内点击行为
通过点击邮件列表内的邮件项这一选择行为,会相应地在下面附件栏和正文栏显示出对应的信息,并把邮件头解析信息返回至txt_Header,其中用到了POP3_ClientMessage、Mail_Message、MIME_Entity方法。
private void lst_messages_SelectedIndexChanged(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;
try
{
toolStrip1.Items["save"].Enabled = false;
toolStrip1.Items["delete"]