UML软件工程组织

用java开发Email工具之发送邮件(2)
作者:冯睿    本文选自:赛迪网  2002年12月18日

现在也许你关心的问题是回应码的格式是怎样的。最左边的一位数字代表操作是否成功,1代表收到命令,2代表操作成功完成,3代表等待后续命令,4代表操作临时未能完成(电子邮件程序可以在当前的邮件传输过程中重新发送命令),5代表操作不能完成(电子邮件程序不能在当前的邮件传输过程中重新发送命令)。第二位数字代表回应的领域,0代表语法错误,1代表消息请求,2代表传输通道,3和4没有指定,5代表与邮件系统相关。最有一位数字对第二位数字做补充说明,这里就不再详述。根据上面的信息,我们可以看出250代表请求的命令已经成功完成;220代表SMTP服务程序正在等待HELO命令;而503代表命令顺序错误。有兴趣的朋友可以参见RFC 2821。

下面提供了一个基于命令行的例子SMTPDemo,这个例子可以帮助你理解基于SMTP的邮件传输机制。这个程序将利用标准端口25连接到一个SMTP服务程序上。为了使程序能够运行,你需要将home更改为你使用的邮件服务器的地址。

// SMTPDemo.java
import java.io.*;
import java.net.*;
class SMTPDemo
{
public static void main (String [] args)
{
String SMTPServer = "home
int SMTPPort = 25;
Socket client = null;
try
{
// 向SMTP服务程序建立一个套接字连接。
client = new Socket (SMTPServer, SMTPPort);
// 创建一个BufferedReader对象,以便从命令行读取用户输入。
BufferedReader stdin;
stdin = new BufferedReader (new InputStreamReader (System.in));
// 创建一个BufferedReader对象,以便从套接字读取输出。
InputStream is = client.getInputStream ();
BufferedReader sockin;
sockin = new BufferedReader (new InputStreamReader (is));
// 创建一个PrintWriter对象,以便向套接字写入内容。
OutputStream os = client.getOutputStream ();
PrintWriter sockout;
sockout = new PrintWriter (os, true);
// 显示同SMTP服务程序的握手过程。
System.out.println ("S:" + sockin.readLine ());
while (true)
{
System.out.print ("C:");
// 读取用户输入。
String cmd = stdin.readLine ();
// 将用户输入的命令发送到SMTP服务程序。
sockout.println (cmd);
// 从套接字读取SMTP服务程序的回应消息并显示在屏幕上。
String reply = sockin.readLine ();
System.out.println ("S:" + reply);
// 如果发送了DATA命令并且获得成功的回应消息,从输入设备读取行,
// 直到读取到完全由句号组成的行时停止, 这些行构成了电子邮件。
if (cmd.toLowerCase ().startsWith ("data") &&
reply.substring (0, 3).equals ("354"))
{
do
{
cmd = stdin.readLine ();
if (cmd != null && cmd.length () > 1 &&
cmd.charAt (0) == '.')
cmd = ".";
sockout.println (cmd);
if (cmd.equals ("."))
break;
}
while (true);
// 从SMTP服务程序中读取回应消息并显示。
reply = sockin.readLine ();
System.out.println ("S:" + reply);
continue;
}
// 如果用户输入QUIT命令,则退出程序。
if (cmd.toLowerCase ().startsWith ("quit"))
break;
}
}
catch (IOException e)
{
System.out.println (e.toString ());
}
finally
{
try
{
if (client != null)
client.close ();
}
catch (IOException e)
{
}
}
}
}

当运行SMTPDemo时,你将会看到下面的输出。其中C:后面是用户的输入,S:后面是SMTP服务程序返回的信息。

S:220 home.digital.com Microsoft ESMTP MAIL Service, Version: 4.0.2195.2966 ready
at Fri, 13 Dec 2002 15:06:58 +0800

当运行SMTPDemo后,邮件服务程序返回了初始化信息。

C:helo digital.com
S:250 home.digital.com Hello [23.2.254.53]

通过发送helo digital.com命令开始邮件传输过程。digital.com是邮件服务器所在域的域名。然后邮件服务程序返回了以250开头的欢迎信息。

C:mail from: rayfeng@digital.com
S:250 2.1.0 rayfeng@digital.com....Sender OK

接下来是输入邮件发送者的信息mail from:。邮件服务程序返回了成功信息。

C:rcpt to: rayfeng@digital.com
S:250 2.1.5 rayfeng@digital.com

然后是通过rcpt to:指定邮件的接收者。

C:data
S:354 Start mail input; end with <CRLF>.<CRLF>
Subject: Test Email
This is the test Email.
.
S:250 2.6.0 HOMEOulkEZ00VNuHKDy00000002@home.digital.com Queued mail for delivery

接下来是输入邮件的内容。发送DATA命令后,等待服务器发送回命令被成功接收的回应消息。当接收到以354开头的回应消息时,就可以输入电子邮件的内容了。完成后以<CRLF>.<CRLF>结束。

C:quit
S:221 2.0.0 home.digital.com closing connection

最后退出发送电子邮件的过程。请注意回应码221,最左边的2代表操作成功,中间的2表示传输通道,1表示连接关闭。

前面我曾讨论过关于附件的问题。通过SMTPDemo也可以发送附件。通过向邮件服务程序发送下面的命令,就可以在邮件中加入file.txt作为附件。

helo digital.net
mail from: rayfeng@digital.com
rcpt to: rayfeng@digital.com
data
Subject: Attachment Demo
Content-Type: multipart/mixed; boundary="***"
--***
Content-Type: text/plain; charset="iso-8859-1"
This message has an attachment.
--***
Content-Type: text/plain; name="file.txt"
Attachment text.
--***--
quit

到此为止,我们介绍了如何用Java实现Email工具的发送功能,并从地层分析了邮件发送的机制,不知您是否已经掌握了这些内容。在下一篇文章中,我们将一起来研究Email工具的接收功能。



版权所有:UML软件工程组织