top
Loading...
Java設計防病毒電子郵件程序之代碼
這兩個程序的操作都很簡單。這兩個程序叫做VirPro01a和VirPro01b,分別與上面討論的假定的情形中的程序A和程序B對應。



程序VirPro01a

VirPro01a程序被設計為把POP3電子郵件服務器作為公共的電子郵件服務器(秘密電子郵件帳號的服務器可以是任何類型的,例如,它可以是典型的WebMail服務器)。本程序在WinXP下使用SDK 1.4.2測試通過。

實例變量

VirPro01a類的開頭定義了一個實例變量列表:

class VirPro01a extends Frame{
String dataPath = "./Messages/";
int numberMsgs = 0;
int msgCounter = 0;
int msgNumber;
String uidl = "";//唯一的POP3消息ID
BufferedReader inputStream;
PrintWriter outputStream;
Socket socket;
String pathFileName;

dataPath變量包含對本地工作文件夾的指針,該文件夾是存儲等待病毒掃描并轉發到秘密電子郵件帳號的消息的地方。

你可能希望使用另一個不同的文件夾。如果需要這樣做,簡單地提供路徑和文件夾名稱(作為字符串)。你可以發現,我的工作文件夾叫做Messages,它是用包含程序的類文件的文件夾的相對路徑指定的。你也可以使用絕對路徑。

剩余的實例變量都是程序用于不同目的的簡單工作變量。

Main方法

下面的main方法確認正確的命令行參數數量,并使用這些參數來實例化VirPro01a類的一個對象。

public static void main(String[] args){
if(args.length != 3){
System.out.println("Usage: java VirPro01a "+ "pubServer userName password");
System.exit(0);
}// if結束
new VirPro01a(args[0],args[1],args[2]);
}// main結束

構造函數

它的構造函數如下:

VirPro01a(String server,String userName, String password){
int port = 110; //pop3郵件端口
try{
//得到套接字,連接到特定服務器的特定端口
socket = new Socket(server,port);
//從套接字得到輸入流
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//從套接字得到輸出流
outputStream = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()),true);
//連接后在命令行屏幕上顯示從服務器接收到的消息
String connectMsg = validateOneLine();
System.out.println("Connected to server "+ connectMsg);
//現在通訊進程處于AUTHORIZATION 狀態。向服務器發送用戶名和密碼。
//命令采用明文、大寫的方式發送。命令后面帶有參數。發送命令。
outputStream.println("USER " + userName);
//得到響應,并確認響應是+OK而不是-ERR。
String userResponse = validateOneLine();
//在命令行屏幕顯示響應
System.out.println("USER " + userResponse);
//向服務器發送密碼
outputStream.println("PASS " + password);
//驗證服務器的響應是+OK 。在過程中顯示響應。
System.out.println("PASS " + validateOneLine());
}catch(Exception e){e.printStackTrace();}

上面的代碼建立了與公共電子郵件服務器的通訊路徑。

WindowListener

下面的代碼使用匿名類實例化了并注冊了一個WindowListener對象,為頁面右上角的“Close”按鈕服務。

this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
//結束與服務器的對話
outputStream.println("QUIT");
String quitResponse =validateOneLine();
//在命令行屏幕上顯示響應
System.out.println("QUIT " + quitResponse);
try{
socket.close();
}catch(Exception ex){ System.out.println("" + ex);}
System.exit(0);
}// windowClosing結束
}// WindowAdapter()結束
);// addWindowListener結束

Final型的本地變量

下面的代碼聲明并初始化了構造函數中的兩個本地變量:

final Button startButton =new Button("Start");
final TextArea textArea =new TextArea(20,50);

這兩個本地變量包含了圖1所示的按鈕和文本區域的指針。(請注意,這兩個本地變量必須使用final標記,因為它們能夠被匿名類中定義的代碼訪問。匿名類或本地類中的代碼不能訪問非final本地變量。)

注冊ActionListener

下面的代碼顯示了用于實例化和注冊按鈕的ActionListener對象的匿名類:

startButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
try{
//現在通訊進程處于TRANSACTION狀態。檢索并保存消息
if(numberMsgs == 0){
outputStream.println("STAT");
String stat = validateOneLine();
//得到消息的數量(字符串)
String numberMsgsStr =stat.substring(4,stat.indexOf(" ",5));
//把字符串轉換為整型
numberMsgs = Integer.parseInt(numberMsgsStr);
}// 如果numberMsgs == 0終止
//注意:Msg數量從1而不是0開始。檢索并保存每個消息。
//每個消息以新行的句點結束
msgNumber = msgCounter + 1;
if(msgNumber <= numberMsgs){
//處理下一個消息。得到并保存來自服務器的消息唯一標識,
//驗證響應
outputStream.println("UIDL " + msgNumber);
uidl = validateOneLine();
//打開輸出文件保存消息。使用UIDL作為文件名
pathFileName = dataPath + uidl;
DataOutputStream dataOut =new DataOutputStream(new FileOutputStream(pathFileName));
//發送RETR命令開始消息檢索進程
outputStream.println("RETR " + msgNumber);
//驗證響應
String retrResponse =validateOneLine();
//從服務器讀取消息的第一行
String msgLine =inputStream.readLine();
//繼續讀取消息直到遇到第一個“.”符號。它標識消息結束。
while(!(msgLine.equals("."))){
//把數據行寫入輸出文件并讀取下一行。
//在寫入輸出文件的時候插入新行的字符。
dataOut.writeBytes(msgLine + "");
msgLine = inputStream.readLine();
}// while結束
//關閉輸出文件。現在消息存儲在以服務器提供的
//唯一ID為文件名的本地文件中。
dataOut.close();
//顯示過程
textArea.append(msgNumber + "");
//增加消息計數器,為下一個消息作準備
msgCounter++;
//禁止用戶為每個新消息按下按鈕
Toolkit.getDefaultToolkit().getSystemEventQueue().
postEvent(new ActionEvent(startButton,ActionEvent. ACTION_PERFORMED,"Start/Next"));
}//如果msgNumber <= numberMsgs就終止
else{//msgNumber > numberMsgs
//沒有更多消息了。禁止 Start/Next 按鈕
startButton.setEnabled(false);
//提示用戶
Toolkit.getDefaultToolkit().beep();
Thread.currentThread().sleep(300);
Toolkit.getDefaultToolkit().beep();
Thread.currentThread().sleep(300);
Toolkit.getDefaultToolkit().beep();
}// else終止
}// try終止
catch(Exception ex){ ex.printStackTrace();}
}// actionPerformed終止
}// ActionListener終止
);// addActionListener終止

ActionListener對象的目的是下載公共電子郵件服務器上的所有消息,把每個單獨的消息放入不同的文件中,并把這些文件存儲在工作文件夾中。

作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗