1、SMTP簡介
SMTP:簡單郵件傳輸協議
(SMTP:Simple Mail Transfer Protocol)即簡單郵件傳輸協議,它是一組用於由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式。它能夠在傳送中接力傳送郵件,傳送服務提供了進程間通信環境(IPCE),此環境可以包括一個網絡,幾個網絡或一個網絡的子網。理解到傳送系統(或IPCE)不是一對一的是很重要的。進程可能直接和其它進程通過已知的IPCE通信。郵件是一個應用程序或進程間通信。郵件可以通過連接在不同IPCE上的進程跨網絡進行郵件傳送。更特別的是,郵件可以通過不同網絡上的主機接力式傳送。SMTP協議屬於TCP/IP協議族,它幫助每台計算機在發送或中轉信件時找到下一個目的地。通過SMTP協議所指定的服務器,我們就可以把E-mail寄到收信人的服務器上了,整個過程只要幾分鐘。SMTP服務器則是遵循SMTP協議的發送郵件服務器,用來發送或中轉你發出的電子郵件。
SMTP 是一種提供可靠且有效電子郵件傳輸的協議。SMTP是建模在 FTP 文件傳輸服務上的一種郵件服務,主要用於傳輸系統之間的郵件信息並提供來信有關的通知。
SMTP 獨立於特定的傳輸子系統,而且僅要求一條可以保證傳送數據單元順序的通道且只需要可靠有序的數據流信道支持。SMTP 重要特性之一是其能跨越網絡傳輸郵件,即“ SMTP郵件中繼”。通常,一個網絡可以由公用互聯網上 TCP 可相互訪問的主機、防火牆分隔的 TCP/IP 網絡上 TCP 可相互訪問的主機,及其它 LAN/WAN 中的主機利用非 TCP 傳輸層協議組成。使用 SMTP ,可實現相同網絡上處理機之間的郵件傳輸,也可通過中繼器或網關實現某處理機與其它網絡之間的郵件傳輸。
在這種方式下,郵件的發送可能經過從發送端到接收端路徑上的大量中間中繼器或網關主機。域名服務系統(DNS)的郵件交換服務器可以用來識別出傳輸郵件的下一跳 IP 地址。
SMTP在傳輸文件過程中使用25號端口
2、發送過程
3、源代碼示例
- package demo.net;
-
- import java.awt.BorderLayout;
- import java.awt.GridLayout;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.net.InetAddress;
- import java.net.Socket;
- import java.util.Scanner;
-
- import javax.swing.*;
-
- /*
- * 發送郵件客戶端
- */
- public class SendMail extends JFrame {
- private JTextField from;
- private JTextField to;
- private JTextField server;
- private JTextArea message;
- private JTextArea comm;
- private Scanner in;
- private PrintWriter out;
-
- public SendMail() {
- // 設置frame
- setSize(500, 600);
- setTitle("send mail");
- setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- setVisible(true);
- this.setLocationRelativeTo(null);
-
- // 往frame中添加組件
- JPanel p1 = new JPanel(new GridLayout(3, 2));
- p1.add(new JLabel("from:"));
- from = new JTextField(20);
- p1.add(from);
-
- p1.add(new JLabel("to:"));
- to = new JTextField(20);
- p1.add(to);
-
- p1.add(new JLabel("SMTP server:"));
- server = new JTextField(20);
- p1.add(server);
- add(p1, BorderLayout.NORTH);
-
- JPanel p2 = new JPanel(new GridLayout(2, 1));
- message = new JTextArea();
- p2.add(new JScrollPane(message));
-
- comm = new JTextArea();
- comm.setEditable(false);
- p2.add(new JScrollPane(comm));
- add(p2, BorderLayout.CENTER);
-
- JPanel p3 = new JPanel();
- JButton sendButton = new JButton("Send");
- p3.add(sendButton);
- add(p3, BorderLayout.SOUTH);
-
- // 給發送按鈕注冊監聽器
- sendButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- comm.setText("");
- sendMail(server.getText().trim(), from.getText().trim(), to
- .getText().trim(), message.getText());
- }
- });
- }
-
- // 發送郵件
- public void sendMail(String server, String from, String to, String message) {
- try {
- Socket s = new Socket(server, 25);
- try {
- in = new Scanner(s.getInputStream());
- out = new PrintWriter(s.getOutputStream(), true/* 表示自動刷新 */);
- String hostName = InetAddress.getLocalHost().getHostName();
-
- receive();
-
- send("HELLO" + hostName);// 握手,成功返回220表示服務就緒
- receive();
-
- send("MAIL FROM:<" + from + ">");//發件人郵箱
- receive();
-
- send("RCPT TO:<" + to + ">");//收件人郵箱
- receive();
-
- send("DATA");//表示開始發郵件內容了
- receive();
-
- send(message);//發送郵件你內容
- send(".");
- receive();
- send("QUIT");
- } finally {
- s.close();
- }
- } catch (IOException e) {
- comm.append("Error: " + e);
- }
- }
-
- // 發送
- private void send(String s) {
- comm.append(s + '\n');
- out.print(s);
- out.print("\r\n");
- out.flush();
- }
-
- // 接收
- private void receive() {
- comm.append(in.nextLine() + '\n');
- }
-
- public static void main(String[] args) {
- new SendMail();
- }
- }