一、设计思想电子邮件指用电子手段传送信件、单据、资料等信息的通信方法。
电子邮件综合了电话通信和邮政信件的特点,它传送信息的速度和电话一样快,又能象信件一样使收信者在接收端收到文字记录。
电子邮件系统又称基于计算机的邮件报文系统。
它承担从邮件进入系统到邮件到达目的地为止的全部处理过程。
电子邮件不仅可利用电话网络, 而且可利用任何通信网传送。
在利用电话网络时, 还可利用其非高峰期间传送信息,这对于商业邮件具有特殊价值。
由中央计算机和小型计算机控制的面向有限用户的电子系统可以看作是一种计算机会议系统。
电子邮件的工作过程遵循客户- 服务器模式。
每份电子邮件的发送都要涉及到发送方与接收方,发送方式构成客户端,而接收方构成服务器,服务器含有众多用户的电子信箱。
发送方通过邮件客户程序,将编辑好的电子邮件向邮局服务器(SMTP服务器)发送。
邮局服务器识别接收者的地址,并向管理该地址的邮件服务器(POP3服务器)发送消息。
一个邮件系统的传输包含用户代理User Agent 传输代理TransferAgent 及接受代理DeliveryAgent 三大部分。
用户代理是一个用户发信和收信的程序, 负责将电子邮件按照一定的标准包装,然后送至邮件服务器, 或由邮件服务器收回。
传输代理负责信件的交换和传输。
将信件传送至适当的邮件主机, 再由接受代理将信件分发至不同的邮件信箱。
传输代理必须要能够接受用户邮件程序送来的信件,解读收信人的地址,根据SMTP协议将它正确无误地传递到目的地。
现在一般的传输代理已采用Sendmail 程序完成工作。
电子邮件到达邮件主机后, 在经接收代理POP协议被用户读取至自己的主机。
电子邮件在发送与接收过程中都要遵循SMTP POP3等协议,这些协议确保了电子邮件在各种不同系统之间的传输。
其中,SMTP负责电子邮件的发送,而POP3则用于接收In ternet 上的电子邮件。
SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。
SMTP协议属于TCP/ IP协议族,它帮助每台计算机在发送或中转信件时找到下一个目的地。
通过SMTP协议所指定的服务器,我们就可以把E—mail寄到收信人的服务器上了,整个过程只要几分钟。
SMTP!务器则是遵循SMTP协议的发送邮件服务器,用来发送或中转你发出的电子邮件。
POP3(Post Office Protocol 3)即邮局协议,目前已发展到第三版,称POP3它规定怎样将个人计算机连接到Internet 的邮件服务器和下载电子邮件的电子协议。
它是因特网电子邮件的第一个离线协议标准,POP3允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循POP3协议的接收邮件服务器,用来接收电子邮件的。
总的来说POP3协议是让用户把服务器上的信收到本地来所需要的一种协议。
本程序为一个基于SMTP和POP3协议的小型EMAIL收发程序,简单的实现了邮件的收发功能。
三、源代码下面给出的是用登录程序的源代码:using System;using System.Collections.Generic; using ponentModel; using System.Data; using System.Drawing; using Syste m. Linq; using System.Text;using System.Windows.Forms; using ; using .Sockets; using Syste m 」O;算法流程图图1算法流程图//导入名字空间//包含定义各种对象集合的接口和类〃包含表示 ASCII 等字符编码的类namespace MailSendOfRecive{public partial class Form3 : Form{public string Conn,Uname,Pwd,Inf; public TcpClient Server;public NetworkStream NetStrm; public StreamReader RdStrm; public Boolean BPass;public string Data;public byte[] szData;public string CRLF = "\r\n";public Form2 Sender;public Form3(){InitializeComponent();}private void Login_Click(object sender, EventArgs e)Conn = "pop."+textBox1.Text.Trim();Uname = textBox2.Text.Trim();Pwd = textBox3.Text;Server = new TcpClient(Conn, 110); try{NetStrm = Server.GetStream();RdStrm = new StreamReader(Server.GetStream(), System.Text.Encoding.Default);RdStrm.ReadLine();Data = "USER "+ Uname + CRLF;szData =System.Text.Encoding.ASCII.GetBytes(Data);// 获取ASCII 值NetStrm.Write(szData,0,szData.Length);RdStrm.ReadLine();Data = "PASS "+ Pwd + CRLF;szData =System.Text.Encoding.ASCII.GetBytes(Data); NetStrm.Write(szData,0,szData.Length);Inf = RdStrm.ReadLine();if (Inf.IndexOf("+OK")>-1){BPass = true;/ / 布尔值设为真Sender = new Form2(Uname, Pwd, textBox1.Text); this.Hide();Sender.Show();}else if (Inf.IndexOf("-OK")>-1)/ / 判断索引//命名空间//定义类//定义用户名、密码//定义服务器// 定义BPass//定义快捷键//定义框架//初始化//用户名//密码//服务器//读取字符并返回{MessageBox.Show(”密码或者用户名错误",”用户验证");//文本框显示信息}Data = "QUIT";szData = System.Text.Encoding.ASCII.GetBytes(Data);NetStrm.Write(szData, 0, szData.Length); //写入数据}catch (System.Exception ex){MessageBox.Show(ex.Message); //文本框显示信息}private void Form3_Load(object sender, EventArgs e)// 定义Form3_Load下面是发送邮件程序源代码using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using ;using .Sockets;using System.IO;using System.Collections;using System.Data.OleDb;namespace MailSendOfRecive{public partial class Form1 : Form{TcpClient smtpSrv;NetworkStream netStm;string CRLF = "\r\n";public List<MailInfo> SMail = new List<MailInfo>(); public Form2 fa;public string Ua, Pw, Sv; //导入名字空间//包含定义各种对象集合的接口和类// 包含表示ASCII 等字符编码的类//命名空间//定义类//提供数据流public Form1(Form2 f,string UN,string Pd,string SR) // 创建Form1{fa = f;Ua = UN;Pw = Pd;Sv = SR;InitializeComponent(); // 初始化}public void WriteStream(string strCmd){strCmd += CRLF; //crlf 表示结束byte[] bw = System.Text.Encoding.Default.GetBytes(strCmd); // 将字符串转为字节数组netStm.Write(bw,0,bw.Length); // 写入网络}private string AuthStream(string strCmd) // 连接服务器输出字符串{try{byte[] by = System.Text.Encoding.Default.GetBytes(strCmd);strCmd = Convert.ToBase64String(by);}catch (System.Exception ex){return ex.ToString();}return strCmd;}public bool tryTran( ref string a){string b = "";b = a;try{byte[] outputb = Convert.FromBase64String(a);a = Encoding.Default.GetString(outputb); return true;}catch (System.Exception ex){a= b;return false;}}public void WritInf(string s)//转换成base64 编码//定义布尔变量//转换数据类型//显示错误// 定义WritInf{ tryTran(ref s); listBoxMsg.Items.Add(s);}private void ButtonSend_Click(object sender, EventArgs e){ listBoxMsg.Items.Clear();try { string data;progressBar1.Visible = true; progressBar1.Value = 1;smtpSrv = new TcpClient("smtp."+Sv,25);//TextBoxSer.Text,25);netStm = smtpSrv.GetStream();StreamReader rdStrm = new StreamReader(smtpSrv.GetStream());WriteStream("EHLO Local");progressBar1.Value++;listBoxMsg.Items.Add(" 输入用户名开始"); WriteStream("AUTH LOGIN");listBoxMsg.Items.Add(rdStrm.ReadLine()); progressBar1.Value++;data = AuthStream(Ua);//data);WriteStream(data);listBoxMsg.Items.Add(rdStrm.ReadLine()); data = AuthStream(Pw);//data);WriteStream(data);listBoxMsg.Items.Add(rdStrm.ReadLine()); progressBar1.Value++;data = "MAIL FROM:<" + TextBoxSend.Text + ">"; WriteStream(data);listBoxMsg.Items.Add(rdStrm.ReadLine()); progressBar1.Value++;data = "RCPT TO:<"+TextBoxRev.Text+">"; WriteStream(data);listBoxMsg.Items.Add(rdStrm.ReadLine()); progressBar1.Value++;WriteStream("DATA");listBoxMsg.Items.Add(rdStrm.ReadLine()); progressBar1.Value++;data = "Date:"+System.DateTime.Now; WriteStream(data);progressBar1.Value++; 〃产生StreamReader来读取数据流//发送命令建立连接//发送命令请求验证//转换编码格式//发送用户名//转换编码格式//发送//发件人地址//收件人地址//数据//日期// 定义ButtonSend_Click//存放smtp 服务器返回的信息//连接smtp 服务器// 取得Networkstream 对象,来发送接收数据data = "From:" + TextBoxSend.Text; WriteStream(data);progressBar1.Value++;data = "To:" + TextBoxRev.Text;WriteStream(data);progressBar1.Value++;data = "SUBJECT:" + textBoxSubject.Text; WriteStream(data);progressBar1.Value++;data = "Reply-To:" + TextBoxSend.Text; WriteStream(data);progressBar1.Value++;WriteStream("");progressBar1.Value++;WriteStream(textBoxMailText.Text); progressBar1.Value++;WriteStream(".");progressBar1.Value++;listBoxMsg.Items.Add(rdStrm.ReadLine()); WriteStream("QUIT");progressBar1.Value++;listBoxMsg.Items.Add(rdStrm.ReadLine()); netStm.Close();rdStrm.Close();MailInfo i = new MailInfo();i.sender = TextBoxSend.Text;i.geter = TextBoxRev.Text;i.Ttile = textBoxSubject.Text;i.NeiRong = textBoxMailText.Text;i.Datatime = DateTime.Now.ToString();SMail.Add(i);MessageBox.Show(”邮件发送成功",”成功");}catch (System.Exception ex){MessageBox.Show(ex.ToString(), " 操作错误"); }}private void Form1_FormClosed(object sender,{Application.Exit();}//发送者//接收者//主题//发送回复地址//表示首部结束,开始正文//点表示邮件内容结束//断开//添加项//释放资源//将发送的消息送到SMail 便于传个收件箱界面//显示信息//显示信息sedEventArgs e)//终止所有程序private void button1_Click(object sender, EventArgs e){ this.Hide();fa.Show(); //隐藏控件fa.GetSenMail(SMail);}private void Form1_Load(object sender, EventArgs e){}}}下面是接收邮件程序源代码using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using ;using .Mail;using .Sockets;using System.IO;using System.Collections;namespace MailSendOfRecive{public partial class Form2 : Form{public TcpClient Server;public NetworkStream NetStrm;public StreamReader RdStrm;public string Data,UsName,Pawd,InEmai;public byte[] szData,other;public List<MailInfo> EMail = new List<MailInfo>(); // public List<MailInfo> DMail = new List<MailInfo>(); public List<MailInfo> SndMail = new List<MailInfo>(); public string CRLF = "\r\n";public FileStream fs;public int InfoID,BackId;public int DeleTxt = -1;DataTable dt = new DataTable();public Form2(string Uname,string Pwd,string IEM) //导入名字空间//包含定义各种对象集合的接口和类// 包含表示ASCII 等字符编码的类//命名空间//定义类//定义服务器链表类//声明写入流//数据表了,类似于数据库,可以存放数据{InfoID = -1;InEmai = IEM;//"pop."+IEM; UsName = Uname; Pawd = Pwd;}private void Inint(){TreeNode Node = treeView1.Nodes.Add("Name", " 邮件归档系统 "); Node.Nodes.Add("Send", " 发件箱 "); Node.Nodes.Add("Recove", " 收件箱 ");Node.Nodes.Add("GuiDang", " 邮件归档 "); // 获取对象的集合 Node.Nodes.Add("HuiShou", " 回收站 ");}private void ShowInfo(){ }private void buttonCon_Click(object sender, EventArgs e)//定义点击事件 {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;//textBoxUser.Text+CRLF; szData =System.Text.Encoding.Default.GetBytes(Data); // 获取编码 NetStrm.Write(szData,0,szData.Length); listBoxStatus.Items.Add(RdStrm.ReadLine());Data = "PASS " + Pawd + CRLF;//textBoxPwd.Text+CRLF; szData =System.Text.Encoding.Default.GetBytes(Data); // 获取编码 NetStrm.Write(szData,0,szData.Length); listBoxStatus.Items.Add(RdStrm.ReadLine());// 获取所有的邮件的大小Data = "STAT " + CRLF;szData = System.Text.Encoding.Default.GetBytes(Data); // 获取编码InitializeComponent(); Inint();dt.Columns.Add("ID",typeof(int));dt.Columns.Add(" 主题 ", typeof(string)); dt.Columns.Add(" 发件人 ", typeof(string)); dt.Columns.Add("时间",typeof(string));dt.Columns.Add(" 含有附件 ", typeof(Boolean));//初始化//为网格添加标题//创建对象//初始化节点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; for (int i = 0; i < Cout;i++ ){MailInfo ou = new MailInfo(); GetInfo(i+1,ref ou); EMail.Add(ou);}ShowInfo();}else{buttonDel.Enabled = false;}buttonCon.Enabled = false; buttonDison.Enabled = true; GuiButton.Enabled = true; buttonDel.Enabled = true; treeView1.Enabled = true;}catch (System.Exception ex){MessageBox.Show(ex.ToString());} }//写入数据private void GetInfo(int ID,ref MailInfo NewInfo){richTexOfInfo.AppendText("\r\n- NewInfo.id =ID; string szTemp; try{string st = Convert.ToString(ID); Data = "UIDL " + st + CRLF;//显示消息框//检索字符串//设置控件属性//对象添加到结尾//控件设为不可用//控件设为不可用//控件设为不可用//显示消息框//按 ID 读取邮件并进行解析\r\n");// 追加文本//获取每个邮件的唯一标示NetStrm.Write(szData, 0, szData.Length); // 写入数据szTemp = RdStrm.ReadLine();richTexOfInfo.AppendText(szTemp + CRLF); // 追加文本Data = "RETR " + st + CRLF;szData = System.Text.Encoding.Default.GetBytes(Data); // 获取编码NetStrm.Write(szData, 0, szData.Length);szTemp = RdStrm.ReadLine(); // 读取字符串并返回richTexOfInfo.AppendText(szTemp + CRLF);} szTemp = RdStrm.ReadLine();}}else}catch (System.Exception ex){listBoxStatus.Items.Add("Error:" + ex.ToString());}}private void buttonDison_Click(object sender, EventArgs e)//退出连接Data = "QUIT "+CRLF;szData = System.Text.Encoding.ASCII.GetBytes(Data); // 获取编码NetStrm.Write(szData, 0, szData.Length);NetStrm.Close();RdStrm.Close();buttonDel.Enabled = false; buttonCon.Enabled = true; buttonDison.Enabled = false;}public bool tryTran(ref string a){try{byte[] outputb = Convert.FromBase64String(a); a = Encoding.Default.GetString(outputb); return true;}catch (System.Exception ex){ return false;}//释放资源//设置控件属性//安照Base64 进行解析流文件//错误信息}private void GetString(ref string a,int s,int e) // 字符串处理{string u1 = "", u2 ="",u3=""; // 初始化int sum;sum = a.IndexOf("B?");u1 = a.Substring(0, s);u2 = a.Substring(sum+2, e-sum-2);byte[] outputb = Convert.FromBase64String(u2);u2 = Encoding.Default.GetString(outputb);u3 = a.Substring(e + 2, a.Length - e - 2);a = u1 + u2 + u3;}private void buttonRead_Click(object sender, EventArgs e) //定义事件{}private void buttonDel_Click(object sender, EventArgs e) // 删除邮件{try{if (InfoID>-1){string st = InfoID.ToString();dt.Rows.Remove(dt.Rows[DeleTxt]);dataGridView1.DataSource = dt;richTexOfInfo.Text = "";MessageBox.Show(”删除操作成功",”操作成功"); 〃显示信息}}catch (System.Exception ex) //显示错误{MessageBox.Show(ex.Message); //显示信息}}private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) //选择点击树节点时触发的事件{dt.Clear();{richTexOfInfo.Text = SndMail[Convert.ToInt32()].NeiRong;}if (dt.Rows.Count>0){this.dataGridView1.DataSource = dt; //获取数据源}} else}private void GuiButton_Click(object sender, EventArgs e) // 进行归档{ treeView1.Nodes["Name"].Nodes["GuiDang"].Nodes.Add("ShiYang", " 实验报告");//获取树节点集合treeView1.Nodes["Name"].Nodes["GuiDang"].Nodes.Add("Other"," 其他邮件"); foreach (MailInfo a in EMail){if (a.Ttile.IndexOf(" 实验报告")> 0) {treeView1.Nodes["Name"].Nodes["GuiDang"].Nodes["ShiYang"].Nodes.Add(a.sender, a.sender); //获取树节点集合}else treeView1.Nodes["Name"].Nodes["GuiDang"].Nodes["Other"].Nodes.Add(a.sender, a.sender);}GuiButton.Enabled = false; //控件设为不可用}private void dataGridView1_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)//点击表格时触发的事件{DeleTxt = e.RowIndex; //获取索引InfoID = (int)this.dataGridView1[0, e.RowIndex].Value; // 获取值foreach (MailInfo a in EMail){if (a.id == InfoID){richTexOfInfo.Text = a.NeiRong; // 获取文本break;}}}public void GetSenMail(List<MailInfo> e) //获取发件模块送的数据{if (e.Count>0){foreach (MailInfo a in e){int i = treeView1.Nodes["Name"].Nodes["Send"].Nodes.Count;treeView1.Nodes["Name"].Nodes["Send"].Nodes.Add(i.ToString(),a.geter);SndMail.Add(a); // 添加对象到结尾处}}}private void button1_Click(object sender, EventArgs e) // 跳到发件界面{Form1 Se = new Form1(this, UsName, Pawd, InEmai);this.Hide();Se.Show();}private void Form2_FormClosed(object sender, FormClosedEventArgs e)//程序退出处理{Application.Exit(); // 停止程序}private void button2_Click(object sender, EventArgs e) // 还原回收站中的数据{treeView1.Nodes["Name"].Nodes["HuiShou"].Nodes.Remove(treeView1.Nodes["Name"].Nodes["HuiShou" ].N odes[BackId.ToString()]); // 获取集合foreach (MailInfo a in DMail){if (a.id == BackId){dt.Rows.Add(new Object[] { a.id, a.Ttile, a.sender, a.Datatime, a.Fujian });//获取集合dataGridView1.DataSource = dt; //获取数据源}}}private void Form2_Load(object sender, EventArgs e){}}public class MailInfo {public int id;public string sender; //寄件人public string geter; //收件人public Boolean Fujian; //是否有附件public string FJname; //附件名称public string Ttile;public string NeiRong; //内容public string Datatime; //日期public MailInfo()//构建MailInfo{Fujian = false;id = -1;sender ="";geter ="";FJname ="";Ttile ="";NeiRong ="";Datatime ="";}}}四、运行结果运行结果有3个界面图3发送邮件界面图4接收邮件界面五、遇到的问题及解决这部分我主要遇到了如下两个问题,其内容与解决方法如下所列:不清楚SMTP和POP3的区别。