电子邮件
一,概述.
无论是工作还是生活,电子邮件已成为和我们密切联系在一起的一项网络活动。我在学校与老师交流使用电子邮件,在公司事务的交流使用电子邮件,网络的方方面面都离不开电子邮件,在了解过了一些简单协议后,来学习下,电子邮件收发过程中使用的各种协议。
其中有以下3种比较常用且重要的协议:
1.SMTP(简单邮件传输协议):主要负责将邮件从一台机器转发至另一台机器。
2.POP3(邮局协议):主要将邮件从邮箱(POP3服务器)传输到本地计算机。
3.IMAP(网络邮件传输协议):主要负责邮件的检索和处理功能,客户端不需要下载邮件到本地,可直接从邮件客户端对服务器上的信件和文件目录进行操作,他是POP3的替代协议。
发送终端将写好的电子邮件通过SMTP协议发送到SMTP服务器,然后SMTP服务器根据收件人的地址,通过SMTP协议转发到相应的SMTP接收服务器上,然后接收端邮件服务器(POP3)把邮件放到接收者的邮箱里,最后收件人登陆邮箱,与POP3服务器连接,从POP3服务器上下载发送来的邮件。
所以下面来介绍下SMTP协议和POP3协议。
二,SMTP协议
1.SMPT服务器默认端口号是25。
2.当需要用户名密码认证的时候,使用的是ESMTP协议
当不需要客户端认证,可以匿名发送邮件,使用的是SMTP协议
3.SMTP定义了多个命令(命令不区分大小写)如下所示
SMTP 命令 | 命令功能 |
---|---|
HELO |
客户端为标识自己的身份而发送的命令(通常带域名) |
EHLO |
使服务器可以表明自己支持扩展简单邮件传输协议 (ESMTP) 命令。 |
MAIL FROM |
标识邮件的发件人;以 MAIL FROM: 的形式使用。 |
RCPT TO |
标识邮件的收件人;以 RCPT TO: 的形式使用。 |
TURN |
允许客户端和服务器交换角色,并在相反的方向发送邮件,而不必建立新的连接。 |
ATRN |
ATRN (Authenticated TURN) 命令可以选择将一个或多个域作为参数。如果该会话已通过身份验证,则 ATRN 命令一定会被拒绝。 |
SIZE |
提供一种使 SMTP 服务器可以指出所支持的最大邮件大小的机制。兼容的服务器必须提供大小范围,以指出可以接受的最大邮件大小。客户端发送的邮件不应大于服务器所指出的这一大小。 |
ETRN |
SMTP 的扩展。SMTP 服务器可以发送 ETRN 以请求另一台服务器发送它所拥有的任何电子邮件。 |
PIPELINING |
提供发送命令流(而无需在每个命令之后都等待响应)的能力。 |
CHUNKING |
替换 DATA 命令的 ESMTP 命令。该命令使 SMTP 主机不必持续地扫描数据的末尾,它发送带参数的 BDAT 命令,该参数包含邮件的总字节数。接收方服务器计算邮件的字节数,如果邮件大小等于 BDAT 命令发送的值时,则该服务器假定它收到了全部的邮件数据。 |
DATA |
客户端发送的、用于启动邮件内容传输的命令。 |
DSN |
启用传递状态通知的 ESMTP 命令。 |
RSET |
使整个邮件的处理无效,并重置缓冲区。 |
VRFY |
确认在邮件传递过程中可以使用邮箱;例如, |
HELP |
返回 SMTP 服务所支持的命令列表。 |
QUIT |
终止会话。 |
4.SMTP的大致流程。
a.客户端与邮件服务器尝试连接,等待邮件服务器返回220 ready的信息。
b.客户端收到220响应码,便会向邮件服务器发送HELO<Mail Server>,这时服务器返回250 OK响应码,表示双方建立连接,随后可以发送邮件。
c.客户端发送以MAIL FROM<发件人E-mail地址>开始,如果E-mail地址正确,那么返回250 OK响应码。
d.然后客户端再发送RCPT TO<收件人E-mail地址>,如果E-mail地址正确,那么返回250 OK响应码。
e.这时发送DATA这个命令,告知服务器将要发送邮件标题及内容,服务器正确返回354 Start mail input的信息 ,随后发送邮件标题和内容。(注意每行必须以<CRLF>结尾)
d.依次发送邮件标题及内容后,必须发送<CRLF>.<CRLF>及回车,换行,句点,回车换行组成,邮件服务器回应250 OK,代表发送成功。
e.最后客户端发出quit指令,表示要求结束连接,如果服务器返回221,怎表示同意,就完成了邮件的正常发送。
5.ESMTP协议,仅仅比SMTP多一个认证的过程,是有用户名和密码通过,才可以。
6.以上的过程如果通过socket来使用那么就必须按照格式发送信息比如
先建立TCP连接 ,然后依次发送:
HELO<Mail Server>\r\n
MALL FROM:<发件人邮件地址>\r\n
RCPT TO:<收件人邮件地址>\r\n
DATA\r\n
<邮件标题和内容>\r\n
\r\n.\r\n
QUIT\r\n
7.如果使用socket发送信息比较麻烦,其实System.Net.Mail中的SmtpClient类已经为我们封装好了。
首先有个MailMessage的实例:MailMessage mailMessage = new MailMessage();
mailMessage就像一封空白邮件一样,可以加入信息比如加入mailMessage.From = new MailAddress('地址');这就加入了发信人的地址,其他请看MSDN。
然后只要使用smtpClient.send(mailmessage);就可以发出邮件了。这样比使用socket,减少了很多工作量。
三,POP3
登陆邮箱代码
//和POP3服务器的110端口号建立TCP连接
TcpClient tpServer = new TcpClient("POP3服务器地址", 110);
//获取客户机和服务器会话的数据流
StreamReader rdStream = new StreamReader(tpServer.GetStream());
string sRec = rdStream.ReadLine();
//向POP3服务器传送账户
sData = "USER " + sPOPUser + CRLF;
byData = System.Text.Encoding.Default.GetBytes(sData.ToCharArray());
nsStream.Write(byData, 0, byData.Length);
//接收POP3服务器反馈数据
sRec = rdStream.ReadLine();
string[] sUserString = sRec.Split(" ".ToCharArray());
if (sUserString[0] == "-ERR")
{
Console.WriteLine("该POP3服务器中没有此帐户!");
return false;
}
//向POP3服务器传送帐户对应密码
sData = "PASS " + sPOPPass + CRLF;
byData = System.Text.Encoding.Default.GetBytes(sData.ToCharArray());
nsStream.Write(byData, 0, byData.Length);
//接收POP3服务器反馈数据
sRec = rdStream.ReadLine();
string[] sPassString = sRec.Split(" ".ToCharArray());
if (sPassString[0] == "-ERR")
{
Console.WriteLine("帐户对应的口令有误!");
return false;
}
获取邮件代码
//向POP3服务器传送获取帐户中邮件数目和占用空间的命令
sData = "RETR 1" + CRLF;
byData = System.Text.Encoding.Default.GetBytes(sData.ToCharArray());
nsStream.Write(byData, 0, byData.Length);
//接收服务器反馈的数据
sRec = rdStream.ReadLine();
//以下代码是收取帐户中的第一封邮件,并提取数据
bool strBody = false ;
string[ ] arrRet =new string[ 6 ] ;
string[ ] arrTemp;
if (sRec != "-")
{
while (sRec != ".")
{
arrTemp = sRec.Split(":".ToCharArray());
if (sRec == "")
strBody = true;
if (arrTemp[0] == "Date")
arrRet[1] = arrTemp[1];
if (arrTemp[0] == "From")
arrRet[2] = arrTemp[1];
if (arrTemp[0] == "To")
arrRet[3] = arrTemp[1];
if (arrTemp[0] == "Subject")
arrRet[4] = arrTemp[1];
if (strBody)
arrRet[5] = arrRet[5] + sRec;
sRec = rdStream.ReadLine();
}
}