一、程序的实现
SMTP (Simple Mail Transfer Protocol) : 电子邮件从客户机传输到服务器或从某一个服务器传输到另一个服务器使用的传输协议。 SMTP 是请求/响应协议,命令和响应都是基于 ASCII 文本,并以 CR 和 LF 符结束。响应包括一个表示返回状态的三位数字代码。SMTP 在 TCP 协议 25 端口监听连接请求。首先,我们创建套接字,然后创建基于套接字输入输出流的过滤器流。可以方便的向服务器整行读取写入数据。相关代码如下:
java.net.Socket s=new java.net.Socket(_smtp.getText(),25); //创建套接字,SMTP默认25端口
_out=new PrintWriter(s.getOutputStream()); //实例化输入输出流
_in=new BufferedReader(new InputStreamReader(s.getInputStream()));
Send()函数用来发送数据后读取服务器的响应。其异常抛出由调用者处理,send函数将发送的信息写入到服务器,同时在状态栏输出,整行读取数据后将响应状态也在侧边栏输出。
主要发送命令如下:
send(null);
send("HELO " + java.net.InetAddress.getLocalHost().getHostName()+"\r\n");//noly
/*用户验证,发送base64加密的用户名密码*/
send("AUTH LOGIN"+"\r\n");//only
send((new sun.misc.BASE64Encoder()).encode(_from.getText().getBytes())+"\r\n");//only
send((new sun.misc.BASE64Encoder()).encode( _pwd.getText().getBytes())+"\r\n");//only
send("MAIL FROM: " + _from.getText()+"\r\n");//only
send("RCPT TO: " + _to.getText()+"\r\n");
send("DATA"+"\r\n");
其中用户验证采用普遍的Base64加密后的用户名,密码。
接着我们发送邮件正文。最先发送的是邮件的相关信息,注意相关信息一般可以造假,除非服务器进行检测。内容如下:
_out.print("cc:" + "这里是抄送内容"+"\r\n");
_out.print("From:" + "来自邮箱"+"\r\n");
_out.print("to:" + "发送的邮件地"+"\r\n");
_out.print("date:" + "时间"+"\r\n");
_out.print("Subject:" + _subject.getText()+"\r\n");
正文采用MIME(Multipurpose Internet Mail Extensions,多功能Internet 邮件扩充服务)来实现发送功能各异的文本。MIME信息由正常的Internet文本邮件组成,文本邮件拥有一些特别的符合RFC 822的信息头和格式化过的信息体(用ASCII 的子集来表示的附件)。这些MIME头给出了一种在邮件中表示附件的特别的方法。我们首先发送正文的相关信息头,然后通过不同的MIME段(每段前也缀以一个特别的头)来发送html、纯文本、加密的附件等。主要代码如下:
_out.print("X-Mailer:Hector’s mail\r\n" //先发送信息头
+"MIMI-Version:1.0\r\n"+"Content-Type:multipart/mixed;boundary=\"#BOUNDARY#\"\r\n\r\n"
+"Content-Transfer-Encoding:7bit\r\n\r\n"
+"This is a multi-part message in MIME format\r\n\r\n"
+"–#BOUNDARY#\r\n" //一个分段标志而已,便于分段发送各种数据
+&q
uot;Content-Type: text/html;charset=gb2312\r\n"
+"Content-Transfer-Encoding:printable\r\n\r\n"
+_body.getText()+"\r\n" //html正文
);
正文发送完之后,我们以send("\r\n"+"."+"\r\n")作为结束,接着我们退出与服务器的链接send("quit"+"\r\n"),最后关闭套接字s.close()。
其中的异常捕获后输出到状态栏。
二、结果分析
下图是运行后的界面和发送的内容,状态栏显示邮件正在发送列队中。
在邮箱中检测到了带HTML的邮件,其中的加粗,换行,斜体html标签都成功实现。
三、程序需要改进的地方
测试在linux下发送失败,原因是Dos和windows采用回车+换行CR/LF表示下一行, (具体参考[关于linux和windows的CR, LF, CR/LF 回车 换行问题])
而UNIX/Linux采用换行符LF表示下一行。经过不断替换换行符,在linux发送成功,需要改换行符的地方:
send("HELO " + java.net.InetAddress.getLocalHost().getHostName()+"\n");
send("AUTH LOGIN"+"\n");
send((new sun.misc.BASE64Encoder()).encode(_from.getText().getBytes())+"\n");
send((new sun.misc.BASE64Encoder()).encode( _pwd.getText().getBytes())+"\n");
为了方便的编辑html文件,可以键入一个html编辑器,另外实现多收件人,以及多附件的发送。
此小程序只是为学习SMTP协议,精力有限,想丰富此程序的功能,请自行调试代码。
程序简陋,仅供学习之用,有问题请到http://www.ourys.com/post/SMTP-JAVA-AUTH_LOGIN.html这里讨论。