Java實現QQ郵件發送客戶端

目錄html

1、前言:QQ郵件發送程序java

2、封裝SMTP操做編程

3、實現多線程接收小程序

4、QQ郵件客戶端界面設計服務器

    一、鏈接按鈕網絡

    二、發送按鈕 多線程

5、QQ郵件發送效果演示app

6、總結socket


1、前言:QQ郵件發送程序

在上一篇《Java網絡編程:實現QQ郵件發送客戶端》,咱們解決了telnet終端發送郵件誤操做帶來的麻煩,實現了本身的簡單Java界面進行發送QQ郵件,界面可直接與smtp.qq.com服務器端創建鏈接,經過命令方式發送郵件信息。tcp

這一篇爲QQ郵件發送客戶端程序設計的下篇,將實現更加完善的功能,不用命令發送方式,相似平常發送郵件,直接編寫郵件標題、內容,而後直接發送便可,基本實現了QQ郵件發送客戶端的功能,操做更加簡便,實現本身的QQ郵件發送端,之後就用這個啦。

2、封裝SMTP操做

原來的終端發送逐步操做以下:

HELO hostname   //回車,hostname能夠是IP或其餘隨意別名
AUTH LOGIN //回車後,先粘貼base64程序編碼的完整郵箱名並回車;再粘貼base64編碼的受權碼並回車
 MAIL FROM:<czh_charzeus@qq.com>   //在這裏填寫本身的郵箱地址,用於發送郵件(注意冒號後面別有空格)
RCPT TO:<czh_charzeus@qq.com>  //接收方的郵箱,在這裏暫時填寫和上面同樣的郵箱地址,即本身發送郵件給本身,驗證是否成功
DATA       //回車,接下來開始發送郵件頭相關內容
Subject: the simple mail     // 郵件的標題,回車 //在這裏再多發送一行空行,來分隔郵件內容,下面就是郵件正文內容
Hello,the mail content! 測試發送郵件! //控制檯中中文會變成?的亂碼,但不影響接受者接收到中文內容
.   //在郵件正文發送完畢後,單獨用一行輸入一個小圓點,做爲結束標誌,而後回車
QUIT   //結束通訊(含4次握手斷開)

所以,咱們要避免這種繁瑣的命令形式,只須要將每一個語句封裝到發送程序裏面,在用戶界面則無需進行命令的輸入,只須要輸入內容。

實現的方法很簡單,只須要在發送按鈕中,把命令加進去就能夠,以下:

tcpMailClient.send("HELO friend"); tcpMailClient.send("auth login"); String userNameBase64= encode(senderMail); tcpMailClient.send(userNameBase64); String authCode = encode("你的受權碼"); tcpMailClient.send(authCode); String msg = "mail from:<"+senderMail+">"; tcpMailClient.send(msg); msg = "rcpt to:<"+receiverMail+">"; tcpMailClient.send(msg); tcpMailClient.send("data"); msg="from:"+senderMail; tcpMailClient.send(msg); msg="to:"+receiverMail; tcpMailClient.send(msg); msg="subject:"+sub; tcpMailClient.send(msg); tcpMailClient.send("\n"); // tcpMailClient.send("這是一封測試java客戶端自動發送功能的郵件。");
tcpMailClient.send(content); tcpMailClient.send("."); tcpMailClient.send("quit");

從代碼能夠看到,當發送按鈕一點擊後,程序會執行全部語句,咱們從上一篇知道,郵件服務器也會返回信息,因此QQ客戶端須要使用多線程的技術,來處理返回信息,避免單線程阻塞致使發送不成功。

3、實現多線程接收

根據前面分析,將客戶端接收的功能交給一個線程處理,就可以達到目的,不會由於接收語句阻塞使得主進程卡住。

因此,將線程放到鏈接按鈕裏面爲好,在成功鏈接服務器以後,程序就啓動線程,時機正好。鏈接按鈕中的線程代碼以下:

//用於接收服務器信息的單獨線程
readThread = new Thread(()->{ String receiveMsg=null;//從服務器接收一串字符
    while ((receiveMsg=tcpMailClient.receive())!=null){ String msgTemp = receiveMsg; Platform.runLater(()->{ taDisplay.appendText(msgTemp+"\n"); }); } Platform.runLater(()->{ taDisplay.appendText("對話已關閉!\n"); }); }); readThread.start();

程序執行發送每一條命令語句的速度比咱們本身輸入發送要快許多,爲了不QQ郵件接收服務器沒法及時響應出錯,程序自動發送過程當中須要設置必定的睡眠等待時間,在send方法設置等待200ms或者500ms。

QQ郵件客戶端實現代碼可見上一篇Java網絡編程:實現QQ郵件發送客戶端,這裏再也不重複介紹。

public void send(String msg){ //輸出字符流,由socket調用系統底層函數,經網卡發送字節流
 pw.println(msg); try { //進行郵件交互,發送smtp指令之間應該暫停一段時間
        Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }

4、QQ郵件客戶端界面設計

界面的設計與以往相似,能夠根據本身的需求設計不一樣的界面風格,可參考本文前言或者總結部分的系列文章進行實現。這裏給出關鍵按鈕的完整代碼。

一、鏈接按鈕

//鏈接按鈕
btConn.setOnAction(event -> {
    String ip=ipAddress.getText().trim();
    String port=tfport.getText().trim();
    try {
 
        tcpMailClient = new TCPMailClient(ip, port);
 
 
        //成功鏈接服務器,接受服務器發來的第一條歡迎信息
        String firstMsg=tcpMailClient.receive();
        taDisplay.appendText(firstMsg+"\n");
                //用於接收服務器信息的單獨線程
                readThread = new Thread(()->{
                    String receiveMsg=null;//從服務器接收一串字符
                    while ((receiveMsg=tcpMailClient.receive())!=null){
                        //lambda表達式不能直接訪問外部非final類型局部變量,須要定義一個臨時變量
                        //若將receiveMsg定義爲類成員變量,則無需臨時變量
                        String msgTemp = receiveMsg;
                        Platform.runLater(()->{
                            taDisplay.appendText(msgTemp+"\n");
                        });
                    }
                    Platform.runLater(()->{
                        taDisplay.appendText("對話已關閉!\n");
                    });
                });
 
                readThread.start();
    } catch (IOException e) {
        e.printStackTrace();
    }
 
});
View Code

二、發送按鈕 

//發送按鈕
btnSend.setOnAction(event -> {
    String senderMail = mail.getText().trim();
    String receiverMail = toMail.getText().trim();
    String sub = subject.getText();
    String content = tfSend.getText();
    try {
 
        tcpMailClient.send("HELO friend");
        tcpMailClient.send("auth login");
 
        String userNameBase64= encode(senderMail);
        tcpMailClient.send(userNameBase64);
        String authCode = encode("你的受權碼");
        tcpMailClient.send(authCode);
        String msg = "mail from:<"+senderMail+">";
        tcpMailClient.send(msg);
 
        msg = "rcpt to:<"+receiverMail+">";
        tcpMailClient.send(msg);
 
        tcpMailClient.send("data");
 
        msg="from:"+senderMail;
        tcpMailClient.send(msg);
 
        msg="to:"+receiverMail;
        tcpMailClient.send(msg);
 
        msg="subject:"+sub;
        tcpMailClient.send(msg);
 
        tcpMailClient.send("\n");
//      tcpMailClient.send("這是一封測試java客戶端自動發送功能的郵件。");
        tcpMailClient.send(content);
 
        tcpMailClient.send(".");
 
        tcpMailClient.send("quit");
 
 
    }catch (Exception e){
        taDisplay.appendText("服務器鏈接失敗!"+e.getMessage()+"\n");
    }
});
View Code

QQ客戶端的程序能夠沿用以前的內容,詳見這篇:基於TCP協議網絡socket編程(java實現C/S通訊)

5、QQ郵件發送效果演示

 細心的讀者能夠發現,在我點擊發送以後,程序卡斷了一會,其實就是由於我設置發送睡眠1000ms,實際能夠發送成功,建議設置200ms或以上!

 發送到本身QQ郵箱:

 

發送到本身的126郵箱進行測試:

6、總結

這一篇爲QQ郵件發送客戶端程序設計的下篇,記錄了實現的關鍵部分,不用命令發送方式,相似平常發送郵件,直接編寫郵件標題、內容,而後直接發送便可,基本實現了QQ郵件發送客戶端的功能,操做更加簡便。根據本篇的知識內容,後面能夠實現更加完善的QQ郵件發送小程序,增長一系列小功能!

若是以爲不錯歡迎「一鍵三連」哦,點贊收藏關注,有問題直接評論,交流學習!


個人博客園:https://www.cnblogs.com/chenzhenhong/p/14331829.html

個人CSDN博客:https://blog.csdn.net/Charzous/article/details/111148425

版權聲明:本文爲博主原創文章,遵循  CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接和本聲明。
本文連接: https://blog.csdn.net/Charzous/article/details/111148425
相關文章
相關標籤/搜索