• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    用Java實現SMTP服務器

    發布: 2007-6-08 17:51 | 作者: 網絡轉載 | 來源: 網絡 | 查看: 162次 | 進入軟件測試論壇討論

    領測軟件測試網 電子郵件傳遞可以由多種協議來實現。目前,在Inte.net 網上最流行的三種電子郵件協議是SMTP、POP3 和 IMAP,下面分別簡單介紹。

      ◆ SMTP 協議

      簡單郵件傳輸協議(Simple Mail Transfer Protocol,SMTP)是一個運行在TCP/IP之上的協議,用它發送和接收電子郵件。SMTP 服務器在默認端口25上監聽。SMTP客戶使用一組簡單的、基于文本的命令與SMTP服務器進行通信。在建立了一個連接后,為了接收響應,SMTP客戶首先發出一個命令來標識它們的電子郵件地址。如果SMTP服務器接受了發送者發出的文本命令,它就利用一個OK響應和整數代碼確認每一個命令?蛻舭l送的另一個命令意味著電子郵件消息體的開始,消息體以一個圓點“.”加上回車符終止。

      ◆ POP3 協議

      郵局協議(Post Office Protocol Version 3,POP3)提供了一種對郵件消息進行排隊的標準機制,這樣接收者以后才能檢索郵件。POP3服務器也運行在TCP/IP之上,并且在默認端口110上監聽。在客戶和服務器之間進行了初始的會話之后,基于文本的命令序列可以被交換。POP3客戶利用用戶名和口令向POP3服務器認證。POP3中的認證是在一種未加密的會話基礎之上進行的。POP3客戶發出一系列命令發送給POP3服務器,如:請求客戶郵箱隊列的狀態、請求列出的郵箱隊列的內容和請求檢索實際的消息。POP3代表一種存儲轉發類型的消息傳遞服務,F在,大部分郵件服務器都采用SMTP發送郵件,同時使用POP3接收電子郵件消息。

      ◆ IMAP 協議

      Internet 消息訪問協議(Internet Message Access Protocol,IMAP)是一種電子郵件消息排隊服務,它對POP3的存儲轉發限制提供了重要的改進。IMAP也使用基于文本命令的語法在TCP/IP上運行,IMAP服務器一般在默認端口143監聽。IMAP服務器允許IMAP客戶下載一個電子郵件的頭信息,并且不要求將整個消息從服務器下載至客戶,這一點與POP3是相同的。IMAP服務器提供了一種排隊機制以接收消息,同時必須與SMTP相結合在一起才能發送消息。

      下面以SMTP發送電子郵件為例講解怎樣用Java 實現SMTP 服務器應用功能,從而完成郵件的發送的。

      SMTP 命令

      SMTP協議是目前網上流行的發送E-Mail的協議,SMTP協議共有14條命令。不過,發一封E-Mail只需用如下5條命令就足夠了,分別為:

      ◆ HELO <SP> <domain> <CRLF> ,與SMTP服務器握手,傳送本機域名;

      ◆ MAIL <SP> FROM:<reverse-path> <CRLF>,傳送發信者的信箱名稱;

      ◆ RCPT <SP> TO:<forward-path> <CRLF>,傳送接收者的信箱名稱;

      ◆ DATA <CRLF>,發送信件數據(包括信頭和信體);

      ◆ QUIT <CRLF>,退出與SMTP服務器的連接。

      編程思路

      首先我們設計一個郵件發送程序的交互界面,界面中包括用戶輸入郵件的收件人、發信人和主題組件的單行文本框,書寫郵件內容的多行文本框等。然后為了能夠實現E-mail的發送和設置,我們設計一個SmtpMail類,它封裝了與郵件服務器之間的Socket 通信操作,以及SMTP 命令的發送和響應信息的接收。

      編程技巧說明

      1.設置窗體和組件

      我們設計了一個MailSendFrame()類繼承Frame 對象,作為容納組件的主窗體。Main()函數實現將窗體啟動時置于屏幕的正中央,窗口定義代碼如下:

    public static void main(String[] args) {
    mailSendFrame mailSendFrame = new mailSendFrame();
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = mailSendFrame.getSize();
    if (frameSize.height > screenSize.height) {
    frameSize.height = screenSize.height;
    }
    if (frameSize.width > screenSize.width) {
    frameSize.width = screenSize.width;
    }
    mailSendFrame.setLocation((screenSize.width - frameSize.width) / 2,
    (screenSize.height - frameSize.height) / 2);
    mailSendFrame.setVisible(true);
    mailSendFrame.show();
    }

      在Main()函數中,首先利用代表系統信息的Toolkit對象得到當前系統中設置的屏幕分辨率,并且用分辨率和窗體的大小作比較,然后,調用MailSendFrame的SetLocation()方法設置窗體的左上角坐標,使窗體的中心和屏幕的中心正好重合,從而將窗體居中。

    //組件實例變量的定義
    Panel panelMain = new Panel();
    Panel panelUp = new Panel();
    Panel panel3 = new Panel();
    Panel panel4 = new Panel();
    Panel panel6 = new Panel();
    Panel panel7 = new Panel();
    TextField txtServer = new TextField();
    TextField txtTo = new TextField();
    TextField txtFrom = new TextField();
    TextField txtSubject = new TextField();
    Panel panel8 = new Panel();
    Label lblFile = new Label();
    Button cmdBrowse = new Button();
    Panel panelDown = new Panel();
    TextArea txtMail = new TextArea();
    Panel panel10 = new Panel();
    Button cmdSend = new Button();
    Button cmdExit = new Button();
    .......
    .......
    panelMain.add(panelUp, null);
    panelUp.add(panel3, null);
    panel3.add(new Label("發信服務器:"), null);
    panel3.add(txtServer, null);
    panelUp.add(panel4, null);
    panel4.add(new Label("收件人:"), null);
    panel4.add(txtTo, null);
    panelUp.add(panel6, null);
    panelUp.add(panel7, null);
    panel7.add(new Label("主題:"), null);
    panel7.add(txtSubject, null);
    panel6.add(new Label("發件人:"), null);
    panel6.add(txtFrom, null);
    panelUp.add(panel8, null);
    panel8.add(new Label("附件: "), null);
    panel8.add(lblFile, null);
    panel8.add(cmdBrowse, null);
    panelMain.add(panelDown, null);
    panelDown.add(txtMail, BorderLayout.CENTER);
    panelDown.add(panel10, BorderLayout.SOUTH);
    panel10.add(cmdSend, null);
    panel10.add(cmdExit, null);
    panelDown.add(new Label(" "), BorderLayout.EAST);
    panelDown.add(new Label(" "), BorderLayout.WEST);
    ........
    ........

      窗體組件的定義都是在Init()方法中完成,設置好收件人、發信人和主題組件的單行文本框,書寫郵件內容的多行文本框,以及附件中的瀏覽按鈕、發送和退出按鈕。
      2.窗體中的事件處理

      事件處理也是在Init()方法中完成。選取附件文件的“瀏覽”按鈕的事件處理,在單擊該按鈕時,打開一個OpenFileDialog 文件對話框,讀取用戶所選取的文件名。打開文件對話框的“瀏覽”按鈕的代碼如下:

    private FileDialog openFileDialog= new FileDialog(this,"打開文件",FileDialog.LOAD);
    public mailSendFrame() {
    try {
    Init();
    }
    catch(Exception e) {
    e.printStackTrace();
    }
    }
    ......
    ......

      單擊“發送”按鈕的事件處理,實現用戶填寫郵件信息的收集和郵件的發送操作!鞍l送”按鈕的代碼如下:

    cmdSend.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(ActionEvent e) {
    cmdSend_actionPerformed(e);
    }
    }

      實現cmdSend_actionPerformed()方法如下:

    void cmdSend_actionPerformed(ActionEvent e) {
    mailSender.setFrom(txtFrom.getText().trim());
    mailSender.setTo(txtTo.getText().trim());
    mailSender.addHeader("Subject",txtSubject.getText().trim()) ;
    mailSender.addData(txtMail.getText()) ;
    if(!lblFile.getText().trim().equals("") )
    mailSender.addAttachment(lblFile.getText().trim());
    mailSender.open(txtServer.getText().trim(),25);
    mailSender.transmit();
    mailSender.close();
    }

      單擊“退出”按鈕的事件處理,實現程序的退出和窗體的關閉!巴顺觥卑粹o和偵聽器的程序代碼如下:

    cmdExit.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(ActionEvent e) {
    cmdExit_actionPerformed(e);
    }
    }
    this.addWindowListener(new java.awt.event.WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    this_windowClosing(e);
    }
    }

      上面程序分別為退出和窗體注冊事件的偵聽器或適配器,它們處理各自的交互動作。實現cmdExit_actionPerformed()和this_windowClosing()方法如下:

    void cmdExit_actionPerformed(ActionEvent e) {
    System.exit(0);
    }
    void this_windowClosing(WindowEvent e) {
    System.exit(0);
    }
      3.SmtpMail 類的實現

      采用Open()方法,建立與郵件服務器之間的TCP/IP 連接,創建套接字,并且得到發送命令所用的輸出流Send 和接收服務器相應所用的輸入流Rev。Open()方法的代碼如下:

    public int open(String serverName, int port){
    try{
    mailSocket = new Socket(serverName, port);
    send = new PrintWriter(mailSocket.getOutputStream(), true);
    recv = new BufferedReader(new InputStreamReader(mailSocket.getInputStream()));
    String s1 = recv.readLine();
    char c = s1.charAt(0);
    if((c == '4') | (c == '5'))
    return 0;
    }
    catch(Exception e){
    return 0;
    }
    return 1;
    }

      在SmtpMail 類中,通過Transmit()方法完成發送任務。Transmit()方法的代碼如下:

    public int transmit(){
    boolean flag = true;
    //發送HELO 命令
    if(domain.length() != 0){
    int i = sendString("HELO " + domain);
    if(i != 1)
    return 0;
    }
    //發送MAIL FROM 命令(發件人)
    if(from.length() != 0){
    int j = sendString("MAIL FROM:" + from);
    if(j != 1)
    return 0;
    }
    //發送RCPT TO 命令(收件人)
    if(to.length() != 0){
    int k = sendString("RCPT TO:" + to);
    if(k != 1)
    return 0;
    }
    //發送郵件正文(DATA 命令)
    if(sendString("DATA") != 1)
    return 0;
    //發送郵件頭信息
    for(int l = 0; l < x_set.size(); l += 2){
    String s = (String)x_set.elementAt(l);
    send.println(s + ": " + x_set.elementAt(l + 1));
    }
    //發送時間及相關內容格式說明
    if(x_set.indexOf("Date") < 0)
    send.println("Date: " + (new Date()).toString());
    ........
    ........

      使用SendString()方法來發送字符串命令,并且接收郵件服務器的響應信息,判斷命令是否被接收。返回1表示命令被拒絕執行,返回0表示命令被接受。SendString()方法的代碼如下:

    private int sendString(String s){
    String s1 = "";
    try{
    send.println(s);
    s1 = recv.readLine();
    }
    catch(Exception e){
    System.out.print(s1);
    return 0;
    }
    if(s1.length() == 0)
    return 0;
    char c = s1.charAt(0);
    return !((c == '4') | (c == '5')) ? 1 : 0;
    }

      使用Close()方法來關閉與服務器之間的套接字連接。該方法發送“QUIT”命令,收到響應消息后,才真正關閉連接。Close()方法的代碼如下:

    public int close(){
    int i = 0;
    try{
    i += sendString("QUIT");
    mailSocket.close();
    }
    catch(Exception e){
    return 0;
    }
    return i == 0 ? 1 : 0;
    }
     mailSendFrame.java源程序代碼如下:

    import java.awt.*;
    import java.awt.event.*;
    public class mailSendFrame extends Frame {
    smtpMail mailSender=new smtpMail();
    Panel panelMain = new Panel();
    Panel panelUp = new Panel();
    Panel panel3 = new Panel();
    Panel panel4 = new Panel();
    Panel panel6 = new Panel();
    Panel panel7 = new Panel();
    TextField txtServer = new TextField();
    TextField txtTo = new TextField();
    TextField txtFrom = new TextField();
    TextField txtSubject = new TextField();
    Panel panel8 = new Panel();
    Label lblFile = new Label();
    Button cmdBrowse = new Button();
    Panel panelDown = new Panel();
    TextArea txtMail = new TextArea();
    Panel panel10 = new Panel();
    Button cmdSend = new Button();
    Button cmdExit = new Button();
    private FileDialog openFileDialog
    = new FileDialog(this,"打開文件",FileDialog.LOAD);
    public mailSendFrame() {
    try {
    Init();
    }
    catch(Exception e) {
    e.printStackTrace();
    }
    }
    public static void main(String[] args) {
    mailSendFrame mailSendFrame = new mailSendFrame();
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = mailSendFrame.getSize();
    if (frameSize.height > screenSize.height) {
    frameSize.height = screenSize.height;
    }
    if (frameSize.width > screenSize.width) {
    frameSize.width = screenSize.width;
    }
    mailSendFrame.setLocation((screenSize.width - frameSize.width) / 2,
    (screenSize.height - frameSize.height) / 2);
    mailSendFrame.setVisible(true);
    mailSendFrame.show();
    }
    private void Init() throws Exception {
    this.setLayout(new BorderLayout());
    panelMain.setLayout(new GridLayout(2,1));
    panelUp.setLayout(new GridLayout(6,1));
    panel3.setLayout(new FlowLayout());
    this.setVisible(true);
    .......
    .......
    //smtpMail.java 的源代碼
    import java.io.*;
    import java.net.Socket;
    import java.util.*;
    public class smtpMail{
    private boolean sendConf=false;
    public static final int OK = 1;
    public static final int ERROR = 0;
    private static final String TEXT = "1";
    private static final String TFILE = "2";
    private static final String BFILE = "3";
    private static final String CPR = "Java 1.0";
    private static final String MAILER = "X-Mailer";
    private static final int BUFFER_SIZE = 48;
    private String DELIMETER;
    private String SEPARATOR;
    private static final int HOW_LONG = 6;
    private static final char SMTP_ERROR_CODE1 = 52;
    private static final char SMTP_ERROR_CODE2 = 53;
    private static final int fillchar = 61;
    private static final String cvt =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    private Socket mailSocket;
    private BufferedReader recv;
    private PrintWriter send;
    private String from;
    private String to;
    private String domain;
    private Vector x_set;
    private Vector body;
    private Vector attach;
    public smtpMail(){
    DELIMETER = "";
    SEPARATOR = "";
    mailSocket = null;
    recv = null;
    send = null;
    from = "";
    to = "";
    domain = "";
    x_set = new Vector();
    body = new Vector();
    attach = new Vector();
    DELIMETER = getId();
    SEPARATOR = System.getProperty("file.separator");
    }
    .........
    .........

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/

    TAG: java 服務器 實現 smtp


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>