学习socket编程之一:用smtp协议发送邮件

写这篇文章的目的是做为我学习socket编程的记录,本身已经没有什么技术含量了,这篇文章的内容基本上全部是参考网上的资料而写出来的,在这里首先感谢研究并写出这些技术文章的同仁。如果你已经了解了这些技术也望多多交流分享啊。我就开始捣鼓了。

以前做的所有项目中,当需要用到发送邮件功能的时候,我的第一个念头就是使用jmail组件。也因为这样自己一直也没有深入研究过smtp协议是怎样工作的。最近的工作中刚好又要发送邮件功能,且不能在服务器上安装第三方组件,恰好自己又开始对socket编程产生兴趣。就想着用socket来实现。

想好了就开始做,首先使用google搜索,可以找出一大堆的关于smtp协议的资料,推荐一个好的网站给大家——中国协议网(http://www.cnpaf.net/),上面有各种协议的介绍和RFC文档。

.SMTP基本命令集:

命令       描述
------------------------------
HELO      向服务器标识用户身份
          发送者能欺骗,说谎,但一般情况下服务器都能检测到。

MAIL      初始化邮件传输
          mail from:
RCPT      标识单个的邮件接收人;常在MAIL命令后面
          可有多个rcpt to:
DATA      在单个或多个RCPT命令后,表示所有的邮件接收人已标识,并初始化数据传输,以.结束。
VRFY      用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令
EXPN      验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用
HELP      查询服务器支持什么命令
NOOP      无操作,服务器应响应OK
QUIT      结束会话
RSET      重置会话,当前传输被取消

如果你的机器上安装了IIS的话,你可以在windows命令窗口输入
telnet localhost 25
helo localhost
mail from: jimyhsu@163.com
rcpt to: jimyhsu@163.com
...
来测试smtp发信了。

呵呵,大概了解了smtp协议后,我们就开始使用socket这个好东西了。socket被成为TCP/IP协议的API,能做的事情太多了。其实现在的socket5已经支持TCP/IP和UDP等协议了。这里我们需要用到的是
System.Net.Sockets.TcpClient和System.Net.Sockets.NetworkStream,大家可以通过msdn多了解System.Net.Sockets的各个成员。

具体代码如下:

//--创建与服务器25端口的连接
            TcpClient SmtpServ = new TcpClient(smtp,25);
            listBox1.Items.Clear();

            
//--显示服务器初始信息
            NetworkStream NetStrm = SmtpServ.GetStream();
            StreamReader RdStrm 
= new StreamReader(SmtpServ.GetStream());        
            listBox1.Items.Add(RdStrm.ReadLine());
            
            sendData 
= "HELO localhost" + CRLF;
            szData 
= System.Text.Encoding.ASCII.GetBytes(sendData.ToCharArray());
            NetStrm.Write(szData, 
0, szData.Length);
            listBox1.Items.Add(RdStrm.ReadLine());

            
//--标志发件人
            sendData = "MAIL FROM:" + "<" + from + ">" + CRLF;
            szData 
= System.Text.Encoding.ASCII.GetBytes(sendData.ToCharArray());
            NetStrm.Write(szData, 
0, szData.Length);
            listBox1.Items.Add(RdStrm.ReadLine());

            
//--标志收件人
            sendData = "RCPT TO:" + "<" + to + ">" + CRLF;
            szData 
= System.Text.Encoding.ASCII.GetBytes(sendData.ToCharArray());
            NetStrm.Write(szData, 
0, szData.Length);
            listBox1.Items.Add(RdStrm.ReadLine());

            
//--准备发送内容
            sendData = "DATA" + CRLF;
            szData 
= System.Text.Encoding.ASCII.GetBytes(sendData.ToCharArray());
            NetStrm.Write(szData, 
0, szData.Length);
            listBox1.Items.Add(RdStrm.ReadLine());

            
//--发送主题
            sendData = "SUBJECT: " + subject + CRLF;
            
//--发送内容
            sendData = sendData + content + CRLF;
            
//--'结束发送
            sendData = sendData + "." + CRLF;
            szData 
= System.Text.Encoding.ASCII.GetBytes(sendData.ToCharArray());
            NetStrm.Write(szData, 
0, szData.Length);
            listBox1.Items.Add(RdStrm.ReadLine());

            
//--退出
            sendData = "QUIT" + CRLF;
            szData 
= System.Text.Encoding.ASCII.GetBytes(sendData.ToCharArray());
            NetStrm.Write(szData, 
0, szData.Length);
            listBox1.Items.Add(RdStrm.ReadLine());

            
//--关闭连接
            NetStrm.Close();
            RdStrm.Close();
            listBox1.Items.Add(
"连接关闭");
            listBox1.Items.Add(
"发送成功");

下一节将讨论ftp协议的socket编程

posted on 2005-06-16 12:38  湘南和也  阅读(3622)  评论(4编辑  收藏  举报