当前位置: 首页 > news >正文

使用SMTP协议发送邮件

使用SMTP协议发送邮件,可以不通过SMTP服务器,直接将邮件发送到邮件服务器。很多服务器端程序可能需要向很多用户发送邮件,直接通过SMTP发送可能是最有效的。

关于SMTP协议定义在RFC821,可以在此看中文版。

第一步:通过目标email查找邮件服务器。
例如:asklxf@sohu.com,其邮件服务器地址为:sohumx.sohu.com

import java.net.*;
import java.io.*;
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;

public class Smtp {

public static void main(String[] args) throws Exception {
// DNS服务器,看看本机的DNS配置
String dns = "dns://192.168.1.1";
// 邮箱后缀:
String domain = "sohu.com";
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
env.put("java.naming.provider.url", dns);
DirContext ctx = new InitialDirContext(env);
Attributes attr = ctx.getAttributes(domain, new String[]{"MX" });
NamingEnumeration servers = attr.getAll();
// 列出所有邮件服务器:
while(servers.hasMore()) {
System.out.println(servers.next());
}
}
}

第二步:直接连接邮件服务器的25端口,用SMTP协议发送邮件。
这里使用sohu信箱,邮件服务器为sohumx.sohu.com,收信人必须在此服务器上:

import java.net.*;
import java.io.*;
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;

public class Smtp {

private static String END_FLAG = "\r\n";

public static void main(String[] args) throws Exception {
String mx = "sohumx.sohu.com";
InetAddress addr = InetAddress.getByName(mx);
Socket socket = new Socket(addr, 25);

InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();

// 连接成功后服务器会响应:
response(in);

// 首先发送HELO命令:
send("HELO
www.javasprite.com" + END_FLAG, out);
response(in);

// 然后发送发件人地址:
send("MAIL FROM: someone@somewhere.com" + END_FLAG, out);
response(in);

// 设置收件人地址:
send("RCPT TO: asklxf@sohu.com" + END_FLAG, out);
response(in);

// 开始发送邮件正文:
send("DATA" + END_FLAG, out);
response(in);

send("From: someone@somewhere.com" + END_FLAG, out);
send("To: asklxf@sohu.com" + END_FLAG, out);
send("Subject: Test without smtp server" + END_FLAG, out);
send("Content-Type: text/plain;" + END_FLAG, out);
send(END_FLAG + END_FLAG, out);

// 发送邮件正文,如果用中文,需要BASE64编码:
send("text message body!" + END_FLAG, out);
// 每行以\r\n结束,不可过长,可拆成多行。

// 以"\r\n.\r\n"作为结束标志:
send(END_FLAG + "." + END_FLAG, out);
response(in);

// 结束并确认发送:
send("QUIT" + END_FLAG, out);
response(in);
in.close();
out.close();
socket.close();
}

public static void response(InputStream in) throws Exception {
byte[] buffer = new byte[1024];
int n = in.read(buffer);
String s = new String(buffer, 0, n);
// 服务器会返回:### Text
// 具体含义见RFC821
System.out.println(s);
}

public static void send(String s, OutputStream out) throws Exception {
byte[] buffer = s.getBytes();
out.write(buffer);
// 不要忘了flush(),否则可能在缓冲区:
out.flush();
}
}

Ok,打开outlook收信,会发现有一封来自someone@somewhere.com的信件。

第三步:处理服务器返回码,各种异常,包装成Java组件以便重用:

public interface SendMail {
void send(String from, String to, String subject, String text)
}

public class SendMailImpl extends Thread implements SendMail {
// TODO: 自己写......
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 华为鸿蒙取代不了安卓,华为鸿蒙2.0可以替代安卓吗,华为鸿蒙2.0优势在哪
  • [讨论]在.NET下获取硬盘序列号的问题
  • html input range修改,HTML Input Range value用法及代码示例
  • html导入图片怎么缩小体积,如何减小网页html体积几点方法介绍
  • 平生事,此时凝睇,谁会凭栏意!(1)
  • html 中写目录列表,如何使用Python生成html目录列表
  • 计算机专业学渣面试,感觉读了计算机专业真的是一条不归路
  • 平生事,此时凝睇,谁会凭栏意!(2)
  • html 根作用域,AngularJS Scope(作用域)
  • html无法引入less样式,@import less样式文件 只有css样式生效, less样式却不生效
  • 平生事,此时凝睇,谁会凭栏意!(3)
  • lol提示游戏环境异常重启计算机,出现LOL游戏环境异常请重启机器怎么解决?
  • HOW TO:如何在 Windows Server 2003 中配置 IPSec 隧道
  • html如何制作艺术字体,影视动画制作软件怎么制作多彩立体字 艺术字体制作软件 字体渐变效果...
  • 计算机学硕很难考吗,计算机考研有多难
  • JavaScript-如何实现克隆(clone)函数
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • ERLANG 网工修炼笔记 ---- UDP
  • Flex布局到底解决了什么问题
  • Linux链接文件
  • Lsb图片隐写
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • Vue学习第二天
  • 关于 Cirru Editor 存储格式
  • 小程序 setData 学问多
  • 源码安装memcached和php memcache扩展
  • 栈实现走出迷宫(C++)
  • 通过调用文摘列表API获取文摘
  • # Spring Cloud Alibaba Nacos_配置中心与服务发现(四)
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (附源码)php新闻发布平台 毕业设计 141646
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (篇九)MySQL常用内置函数
  • (四)Linux Shell编程——输入输出重定向
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (转) Android中ViewStub组件使用
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • (转)视频码率,帧率和分辨率的联系与区别
  • (转载)虚函数剖析
  • (自用)仿写程序
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .bat批处理出现中文乱码的情况
  • .NET Project Open Day(2011.11.13)
  • .NET连接MongoDB数据库实例教程
  • @Autowired 与@Resource的区别
  • @Controller和@RestController的区别?
  • @WebServiceClient注解,wsdlLocation 可配置
  • [AndroidStudio]_[初级]_[修改虚拟设备镜像文件的存放位置]
  • [Angular] 笔记 16:模板驱动表单 - 选择框与选项
  • [bzoj1038][ZJOI2008]瞭望塔