基于C#平台下利用POP3和SMTP协议的邮件归档系统

来源:互联网 发布:java访问者模式 编辑:程序博客网 时间:2024/05/16 18:03

今天对电脑进行整理,发现电脑上有一个帮同学做的毕设代码,挺简单的,但是当成做的时候吃了不少苦头,现在都毕业了,就放上来给新手分享一下。好了话不多说。

首先了解一下POP3和SMTP协议,他们是两个网络传输协议,一个负责发邮件的,一个负责收邮件。如果你是软件专业科班出生的,应该有一门课负责讲计算机网络的,你可以看以下,如果没有可以网上搜一下POP3和SMTP。总的来说,我们可以把他们每一个看做实现Windoes的某些功能的cmd命令组合,你输入的正确的命令格式就可以获得对应的结果,然后你根据上一步进行想要的操作。我通过POP3收邮件的过程来举一个更简单的例子:POP3就像是抗战的时候地下党碰头暗号的集合,你就把邮箱的服务器当成接头的A,然后你编写的程序就是某个抗日英雄B,你现在要获得一些武器打鬼子。首先是身份的验证,先找到某条街道的某个茶馆,你的程序对应的就是找到邮箱服务器和端口。下一步,用暗号对你的身份进行验证:B:你这碗怎么卖?A:5块钱一斤,B:我要半打。(好像电视剧的接头暗号都有病,他卖碗轮斤卖,你买碗轮打买),相对应的:你的程序发送几个字符串过去:"USER +你的邮箱号码+结束符“,然后服务器收到,发一个指令过来:+OK,然后你就要发送你的账号的密码发过去:”PASS +你的账号的密码+结束符“,他在发个+OK过来,这是你们的连接就建立起来了。也就是例子中A和B双方都知道是自己人,这时候如果B说:我现在手里缺根扫帚(扫帚表示手枪的意思),然后A说:好的,一会我送到你家里去。我们来对应的比如你要知道你的邮箱中的邮件的数量你就可以发:”STAT +结束符“,然后服务器就发送:”+OK 6 87921“,你就要注意,这个数据分为3段第一段是没有什么实际用途的,第2段表示邮箱中的邮件的数量,第3段表示邮件的总大小。跟着就是相似的,你要干嘛就发对应的指令就够了。于是B就这样从A那里获得了许多的军火,最后当你用完要拜拜的,A和B不能不离开吧。所以当你的邮箱用完了要跟服务器说”QUIT +结束符“的。这样我们就获得了我们要的数据:下面附上POP3指令:

命令参数状态描述userusername认可此命令与下面的pass命令若成功,将导致状态转换passpassword认可 apopname,digest认可一种安全传输口令的办法,digest是md5消息摘要,执行成功导致状态转换,请参见RFC 1321stat不用加参数处理请求服务器发回关于邮箱的统计资料,如邮件总数和总字节数uidl邮件的编号处理返回邮件的唯一标识符,pop3会话的每个标识符都将是唯一的list同上处理返回邮件数量和每个邮件的大小retr同上处理返回由参数标识的邮件的全部文本dele同上处理服务器将由参数标识的邮件标记为删除,由quit命令执行rset不需要参数处理服务器将重置所有标记为删除的邮件,用于撤消dele命令top邮件的编号,n处理服务器将返回由参数标识的邮件前n行内容,n必须是正整数noop不需要参数处理服务器返回一个肯定的响应,不做任何操作。quit不需要参数更新退出当然我们这个发送的命令是经过网络的,所以要用到网络编程的类,因此双方在通讯前要勇敢网络流建立起通信的连接。下面是网络流通讯的类的定义:
        public TcpClient Server;//TCP通信类
        public NetworkStream NetStrm;//网络流
        public StreamReader RdStrm;//通信流读取
        public string Data,UsName,Pawd,InEmai;
        public byte[] szData,other;
        public string CRLF = "\r\n";

下面是POP3的命令使用的代码():
Server = new TcpClient("pop."+InEmai, 110);//            try            {                NetStrm = Server.GetStream();                RdStrm = new StreamReader(NetStrm,System.Text.Encoding.Default);                listBoxStatus.Items.Add(RdStrm.ReadLine());                Data = "USER " + UsName + CRLF;//发送用户名                szData = System.Text.Encoding.Default.GetBytes(Data);                NetStrm.Write(szData,0,szData.Length);                listBoxStatus.Items.Add(RdStrm.ReadLine());                Data = "PASS " + Pawd + CRLF;//密码                szData = System.Text.Encoding.Default.GetBytes(Data);                NetStrm.Write(szData,0,szData.Length);                listBoxStatus.Items.Add(RdStrm.ReadLine());                //获取所有的邮件的大小                /*Data = "LIST" + CRLF;                szData = System.Text.Encoding.Default.GetBytes(Data);                NetStrm.Write(szData, 0, szData.Length);                bool Out = false;                while (!Out)                {                    try                    {                        listBoxStatus.Items.Add("LIST " + RdStrm.ReadLine());                       }                    catch (System.Exception ex)                    {                    break;                    }                    Out = RdStrm.EndOfStream;                }*/                Data = "STAT " + CRLF;                szData = System.Text.Encoding.Default.GetBytes(Data);                NetStrm.Write(szData,0,szData.Length);                string st = RdStrm.ReadLine();                MessageBox.Show(st);                listBoxStatus.Items.Add(st);                st = st.Substring(4, 2);//获取邮箱信息,然后得出邮件的个数                MessageBox.Show(st);                int Cout = Int32.Parse(st);                if (Cout>0)                {                                     buttonDel.Enabled = true;                    //listBoxStatus.Items.Clear();                    //listBoxOpe.Items.Clear();                    for (int i = 0; i < Cout;i++ )                    {                        //listBoxOpe.Items.Add("第" + (i + 1) + "封邮件");                        MailInfo ou = new MailInfo();                        GetInfo(i+1,ref ou);                        EMail.Add(ou);                    }                    ShowInfo();                                    }                else                 {                   // listBoxOpe.Enabled = false;                                     buttonDel.Enabled = false;                }                buttonCon.Enabled = false;                buttonDison.Enabled = true;                GuiButton.Enabled = true;                buttonDel.Enabled = true;                treeView1.Enabled = true;            }            catch (System.Exception ex)            {                //listBoxStatus.Items.Add("错误" + ex.ToString());                MessageBox.Show(ex.ToString());            }
这里声明,代码是可以用的,这个是我花了8个小时给我同学写的毕业设计,8个小时内要对毕设做需求分析,找资料,写代码,修改代码,时间很紧的,因此程序的功能不可能完善和强大。有纰漏和不足的地方还请包涵,毕竟本文只是用于交流。还有smtp也是类似的,我们可以举一反三,要代码的可以到我的CSDN空间下,另外POP3是不提供查询邮件是否阅读了的,你要是想实现这个功能可以用UIDL指令获得每个邮件的唯一编码,然后存在本地数据库里面,一但你在程序里面打开了就要将打开的信息和邮件关系起来——写进数据库,这样就能实现判断邮件是否已经阅读了。最后,说明当你使用RETR指令进行获取邮件的信息时,获得的是Base64编码的文件,如何想看未解码的,可以用RETE命令下载,在程序解码的文本框中显示出来,自己琢磨,这样很有趣。我只在程序里面进行了简单的解码,附件里面我的程序只能解析文本格式的附件,Word文档不能解码,其他的尚未测试。本文只是讲解POP3和SMTP协议的编程,欢迎留言探讨。