编写可在线收发E-mail的Java Applet

来源:互联网 发布:未来网络 南京 垃圾 编辑:程序博客网 时间:2024/04/28 09:53
<script type="text/javascript">google_ad_client = "pub-8800625213955058";/* 336x280, 创建于 07-11-21 */google_ad_slot = "0989131976";google_ad_width = 336;google_ad_height = 280;//</script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>

编写可在线收发E-mail的Java Applet

   说起Java,有些人可能会想到一些用于修饰主页的Applet,例如著名的水光倒影Lake.class等。其实这些Applet只是Java应用的很小一个方面。作为一种新兴的网络语言,Java用于编写基于TCP/IP的应用才算用到了点子上。在编写TCP/IP的应用方面,Java是我所用过的编程语言中最简洁、最快速的。本文将讨论如何用Java来编写可根据SMTP和POP3协议来收发E-mail的Java Applet。

  一.Java网络编程初步

  1.建立TCP/IP连接

  Socket类中的构造函数Socket(String host,int port)用于创建一个Socket,并与指定的主机(host)及端口(port)连接。由于受到Java Applet安全机制的限制,主机名不可以任意指定,而应和被调用的Applet所在主机的名字相同。因此,可先由GetCodeBase方法取得浏览器当前读取的CLASS文件所在的URL,再通过GetHost方法从该URL返回用字符串表示的该主机的名称。例如从http://person.zj.cninfo.net/~caveman/这个URL中可以返回用字符串表示的主机名"person.zj.cninfo.net"。

  关于标准端口地址的值一般是:SMTP为25、POP3为110、FTP为21等,当然也有的主机用的是非标准的端口,在使用之前最好先确定一下。

  2.数据的发送与接收

  使用Socket类中的GetOutputStream方法可以取得与当前Socket对应的输出数据流,用DataOutputStream类中的WriteBytes方法可以逐个字符地将数据写入到输出数据流中。

  使用Socket类中的GetInputStream方法可以取得与当前Socket对应的输入数据流,用DataInputStream类中的ReadLine方法可以逐行地读取输入数据流中的数据。

  3.关闭TCP/IP连接

  可以用Socket类中的close方法来关闭TCP/IP连接。

  二.基于SMTP协议发送E-mail的Java Applet

  1.SMTP协议和服务器

  SMTP(Simple Mail Transfer Protocol)协议是目前网上流行的发送E-mail的协议,SMTP协议共有14条命令。不过,发一封E-mail只需用如下5条命令就足够了(见表1)。

  表1

   命 令 功 能

  HELO <SP> <domain> <CRLF> 与SMTP服务器握手,传送本机域名

  MAIL <SP> FROM:<reverse-path> <CRLF>传送发信者的信箱名称

  RCPT <SP> TO:<forward-path> <CRLF> 传送接收者的信箱名称

  DATA <CRLF> 发送信件数据(包括信头和信体)

  QUIT <CRLF> 退出与SMTP服务器的连接

  

  除了ISP提供的SMTP服务器以外,国内一些存放免费个人主页的服务器的SMTP端口也是打开的,如果该服务器对外来的E-mail没有增加RELAY限制(例如网易nease.net就有此限制),那么也可以把它当作SMTP服务器来用。如Person.zj.cninfo.net等,在这些服务器上放一个下面要编的Java Applet和调用它的htm文件,用户就可以实现在线发送E-mail了。

  2.SMTPtester.java中的主要程序

  该Java Applet用了三个文本条(TextField)部件tf1、tf2和tf3,它们分别用来供用户输入发信者的信箱名称、接收者的信箱名称和信件的标题;还用了两个文本区(TextArea)部件ta1和ta2,ta1供用户输入信体内容,ta2用来显示Smtp服务器的应答信息和出错信息等;当然还用了一个按钮(Button)部件bu1,用户输入正确的信息后,用鼠标点击一下它,信件就可以被发出去了。

  事件捕获处理程序见程序1:

  public boolean handleEvent(Event event1)

  {

   if ((event1.target != bu1) || (event1.id != 1001))

   /*如果不是按钮bu1被鼠标按下*/

   {

   return false;

   }

   if (!((tf1.getText().length() == 0) || (tf2.getText().length() == 0)))

   /*如果发信者和收信人的信箱名称都填好了,执行发信程序Bu1run*/

   { bu1.disable();

   bu1run();

   return true;

   }

   ta2.appendText("Please give me enough information to send your email!/n");

   return true;

  }

  (程序1)

  发送E-mail程序bu1run见程序2:

  public void bu1run()

  {

   try

   {

  Socket socket1= new Socket(getCodeBase().getHost(),25);

  /*建立与smtp服务器的连接*/

   DataOutputStream dataout2= new DataOutputStream(socket1.getOutputStream());

   DataInputStream dataIn3= new DataInputStream(socket1.getInputStream());

   GetReply(dataIn3);

  dataout2.writeBytes("HELO person.zj.cninfo.net/r/n");

  /*开始按SMTP协议发信*/

   GetReply(dataIn3);

   dataout2.writeBytes("MAIL FROM: " tf1.getText() "/r/n");

   GetReply(dataIn3);

   dataout2.writeBytes("RCPT TO: " tf2.getText() "/r/n");

   GetReply(dataIn3);

   dataout2.writeBytes("DATA/r/n");

   GetReply(dataIn3);

   dataout2.writeBytes("From: " tf1.getText() "/r/n");

   dataout2.writeBytes("To: " tf2.getText() "/r/n");

   dataout2.writeBytes("Subject:" tf3.getText() "/n/n" ta1.getText() "/r/n./r/n");

   GetReply(dataIn3);

   dataout2.writeBytes("QUIT/r/n");

   GetReply(dataIn3);

  socket1.close();

  /*退出连接*/

   bu1.enable();

   return;

   }

   catch (java.io.IOException IOException0) /*捕获IO错误*/

   {

   ta2.appendText("Error!/n");

   bu1.enable();

   return;

   }

  }

  (程序2)

  接收服务器应答程序GetReply见程序3:

  void GetReply(DataInputStream dataIn1)

  {

   String string2;

   string2= "";

   try

   {

   string2= dataIn1.readLine();

   ta2.appendText(string2 "/n");

   }

   catch (java.io.IOException IOException0)

   {

   ta2.appendText("Error!/n");

   bu1.enable();

   return;

   }

  }

  (程序3)

  3.实例运行

  在http://person.zj.cninfo.net/~caveman上已经放了编译好的SMTPtester.class和调用它的smtp.htm,图1是该Applet在运行时的画面,这时这封信已被发往caveman@nease.net了!

  

  三.基于POP3协议读取E_mail的Java Applet

  1.POP3协议和服务器

  POP3(Post Office Protocol version 3)是一种常用的网络协议,用于从远程服务器的信箱里收取E_mail,它的常用命令根据连接时的不同状态有:

  (1)授权状态(AUTHORIZATION state)

  User<SP><name><CRLF> 用户名

  Pass<SP><string><CRLF> 用户密码

  Quit<CRLF> 退出

  (2)执行状态(TRANSACTION state)

  STAT<CRLF> 信箱状态,即信箱内共有几封信,总共大小(8进制表示)等。

  LIST<SP><msg><CRLF> 不用msg参数时显示每封信的大小列表,用msg参数时显示编号为msg的信件的长度(8进制表示)。

  TOP<SP><msg><SP><n><CRLF> 取编号为msg的信件的信头(head)和部分信体(body),n=0时只取信头,n≠0时取信头和信体的前n行。该命令为可选命令,有些POP3服务器软件不支持它。

  RETR<SP><msg><CRLF> 读取编号为msg的信件。

  DELE<SP><msg><CRLF> 删编号为msg的信件,其实只是作个标记,真正删除要到更新状态。

  (3)更新状态(UPDATE state)

  QUIT<CRLF> 退出并把做过DELE标记的邮件删掉。

  另外还有NOOP、LAST、RSET、RPOP等命令用得较少。

  与SMTP服务器的情况相似,除了ISP提供的POP3服务器外,国内的一些存放免费个人主页的服务器也提供POP3服务(例如网易nease.net)。用户在获得免费主页的同时也可以得到一个POP3信箱,例如我的信箱为caveman@nease.net,在服务器上放一个下面要编写的Applet和调用它的htm文件,在线运行它,输入正确的用户名和密码后就可以读取E-mail了。

  2.POP3tester.java中的主要程序

  该Java Applet共用了三个文本条(TextField)部件tf1、tf2和tf3,它们分别用来供用户输入用户名、密码和要读取的E-mail的编号(为0时,只取信箱状态不读信);还用了一个文本区(TextArea)部件ta2,用来显示POP3服务器的应答信息、信件内容和出错信息等;当然还用了一个按钮(Button)部件bu1,用户输入正确的信息后,用鼠标点击一下它,就可以读取指定的信件了。

  事件捕获处理程序与SMTPtester中的一样,读取E-mail程序bu1run见程序4:

  public void bu1run()

  {

   try

   {

  Socket socket1= new Socket(getCodeBase().getHost(), 110);

  /*连接POP3服务器*/

   DataOutputStream dataout2= new DataOutputStream(socket1.getOutputStream());

   DataInputStream dataIn3= new DataInputStream(socket1.getInputStream());

   GetReply(dataIn3);

  dataout2.writeBytes("USER" tf1.getText() "/r/n");

   GetReply(dataIn3);

   dataout2.writeBytes("PASS" tf2.getText() "/r/n");

   GetReply(dataIn3);

  dataout2.writeBytes("STAT/r/n");

  /*信箱状态*/

   GetReply(dataIn3);

   dataout2.writeBytes("LIST/r/n");

  /*信件长度列表*/

   GetReply2(dataIn3);

   ta2.appendText("/n");

   if (tf3.getText().equals("0") == false)

   {

   dataout2.writeBytes("RETR" tf3.getText() "/r/n");

   /*读取指定信件*/

   GetReply2(dataIn3);

   ta2.appendText("/n");

   }

   dataout2.writeBytes("QUIT/r/n");

   GetReply(dataIn3);

   socket1.close();

   bu1.enable();

   return;

   }

   catch (java.io.IOException IOException0)

   {

   ta2.appendText("Error!/n");

   bu1.enable();

   return;

   }

  }

  (程序4)

  接收服务器应答程序GetReply和GetReply2见程序5:

  void GetReply2(DataInputStream dataIn1)

  {

   String string2;

   string2= "";

   try

   {

  for (string2=dataIn1.readLine();

  (string2.equals(".")=false);

  string2=dataIn1.readLine())

  /*List和Retr命令的应答虽然有多行,但都用一句"."作为结束,可据此取应答信息*/

   {

   ta2.appendText(string2 "/n");

   }

   }

   catch (java.io.IOException IOException0)

   {

   ta2.appendText("Error!/n");

   bu1.enable();

   return;

   }

  }

  (程序5)

  读取单句应答的程序GetReply和SMTPtester中的相同,因为在与POP3服务器对话时,List和Retr的应答不只一句,因此又编了一个GetReply2程序来处理这个问题。

  3.实例运行

  在http://www.netease.com/~caveman上已经放了编译好的POP3tester.class和调用它的POP3.html,图2是该Applet运行时的画面,刚才在person.zj.cninfo.net上用SMTPtester发出的那封信已到了我网易的信箱里了。

  

  四.程序的改进

  以上两个Java Applet还很不完善,在加强错误捕获、对邮件附件的支持等方面需要改进的地方还很多。另外,根据上面提到的一些基本方法,只需稍加变化,还可以用Java来实现其他网络协议,如FTP、NEWS等。   

作者联系信箱

作者主页:http://www.netease.com/~caveman

原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一汽夏利股票 一汽大众速腾 上汽和一汽哪个质量好 一汽奔腾t77三大件质量垃圾 一汽大众电话 一汽解放汽车有限公司 上海大众一汽大众 一汽大众速腾2012 一汽大众宝来 探月一汽大众 000800一汽轿车 一汽大众所有车型图片 大众一汽大众 一汽大众探歌价格 一汽客服电话 一汽大众上汽大众 一汽解放汽车 一汽大众客服电话 一汽大众高尔夫 一汽大众迈腾 一汽大众汽车报价 中国一汽奔腾 中国一汽汽车 天津一汽夏利 一汽汽车报价及图片 一汽所有车型 一汽货车报价及图片 一汽大众长春 中国一汽suv报价 一汽大众4s店电话 一汽大众车型及价格 一汽大众捷达多少钱 一汽骏派d60怎么样 一汽大众报价 一汽大众新宝来 一汽大众4s店报价 一汽迈腾报价 一汽奔腾b70价格 一汽大众速腾报价 一汽大众迈腾4s店 一汽森雅4s店地址