面對Outlook Express、Foxmail、Eudora、飛揚、親筆信等琳琅滿目的電子郵件軟件,你是否也躍躍欲試,想自己編寫一個呢?按下面步驟,你就可以實現這個願望。
一、先試試手工發信
在Foxmail的發信狀態窗口中,常會顯示一行不斷變化的字符:比如MAIL FROM:、RCPT TO、DATA等等,表示工作狀態。但是其內部機制是怎樣的呢?讓我們來“模擬”一下電子郵件軟件發信的過程。
先運行Windows95/98中的TELNET.EXE。在其“終端/首選項”菜單中打開“局部回顯”。打開“連接”菜單,選擇“遠程系統”菜單項,打開一個對話框。在“宿主名稱”一欄填入你的發信服務器的地址,在“端口”一欄填上25,然後開始連接。
接通以後,會出現類似下列字符:
220 XXX Sendmail ...
其中220是SMTP服務器的返回碼,表示已經准備好,准備發信,SENDMAIL是UNIX系統中負責發信的SENDMAIL進程,XXX是服務器的名字。
首先,必須向服務器表明自己的身份,以便系統自動撰寫日志。該命令格式為:
HELO你的主機名稱
完成後,服務器返回250,表示接受。現在可以告訴服務器你的發信地址,以便對方回信或發送失敗後退信。
MAIL FROM:你的電子郵件地址
注意其中的冒號不能省略。如果系統認可,同樣返回250。這時,就可以告訴SMTP服務器你的信要發給誰。請輸入:
RCPT TO:收件人的地址
這個命令如果多次使用,就表示把這封信同時發給多個收件人。收到返回的250代碼以後,就可以開始傳輸數據了。打入DATA命令並回車,看見返回碼354以後,即可開始輸入郵件的內容。內容結束時,再在新的一行中單獨打一個英文句號,再回車,就告訴服務器你的信輸完了。這時可以收到服務器返回的250代碼,表示OK。
最後,鍵入QUIT命令,終止這個TELNET會話。服務器返回221後,會主動斷開連接。
二、自己寫個小程序
我們的目的是設計一個VB程序,讓它來完成這一系列發信動作。因此,必須了解Visual Basic中的Winsock通信控件的使用方法。
打開VB5,新建一個“標准EXE”工程,在“工程/部件”菜單中,增加Microsoft Winsock Control 5.0控件。Winsock控件的LocalPort屬性是用來設置本地主機使用的網絡端口,一般是25。RemoteHost和RemotePort屬性可以設置同哪台網絡服務器的哪個端口進行通信,在這裡我們把RemotePort設成25表示與SMTP服務器進行連接。Protocol屬性設為0-sckTCPProtocol,表示使用TCP協議。
Winsock有幾個方法是我們所需要的。Connect方法,用於設置好上述四個屬性後開始連接遠程主機,Winsock收到數據時,產生DataArrival事件。在這個事件中你可以用GetData方法獲取收到的數據。另外,也可以用SendData方法發送數據。
掌握了這些資料,我們就可以設計一個簡單的發送程序。程序中用到的控件如下:
剛剛連通時和每個命令執行後,要檢查服務器的返回碼,所以必須把發送郵件的部分放在Winsock1_DataArrival事件中。實現此功能的代碼如下:
Private Sub cmdSend_Click()
Winsock1.RemoteHost = txtServer.Text
Winsock1.Connect
End Sub
----------------------Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim Data As String
Winsock1.GetData Data
Select Case Val(Data)′處理返回碼
Case 220′如果是剛剛連通,則發送helo命令,並設置標志為helo,以便識別
Tag =″helo″
Winsock1.SendData″helo″&txtServer.Text&vbCrLf
Case 250 ′如果返回250(OK)
Select Case Tag ′則判斷執行命令時設置的標志,以區分剛執行了哪條命令
Case″helo″
Winsock1.SendData″mail from:″&txtFrom.Text&vbCrLf
Tag =″mail″
Case″mail″ ′如果剛執行了MAIL命令,則執行RCPT命令
Winsock1.SendData″rcpt to:″&txtTo.Text&vbCrLf
Tag =″rcpt″
Case″rcpt″ ′如果剛執行了RCPT命令,則執行DATA命令
Winsock1.SendData″data″&vbCrLf
Tag =″data″
Case″data″ ′如果剛執行了DATA命令,則執行QUIT命令
Winsock1.SendData″quit″&vbCrLf
Tag =″quit″
End Select
Case 251
Winsock1.SendData″data″&vbCrLf
Tag =″data″
Case 354
Winsock1.SendData″From:″&txtFrom.Text&vbCrLf&″To:″&txtTo.Text&vbCrLf&″Subject:″&txtSubject.Text&vbCrLf&″Date:″&Now()
Winsock1.SendData″MIME-Version: 1.0″&vbCrLf&″Content-Type: text/plain;charset=″″gb2312″″″&vbCrLf&″Content-Transfer-Encoding: 8bit″&vbCrLf&vbCrLf
Winsock1.SendData txtContent.Text
Winsock1.SendData vbCrLf&″.″&vbCrLf
Case 221′如果是QUIT命令的返回碼,就清除命令執行標志,准備斷開連接
Tag =″″
Case Else ′如果是其他返回碼,就提示錯誤
Winsock1.SendData″quit″&vbCrLf
Tag =″quit″
MsgBox″錯誤″&Data
End Select
End Sub
三、郵件頭及編碼
當你收到剛才給自己發的郵件,可能會發現,這封信既沒有“發件人”、“收件人”,也沒有“主題”和“日期”。這是由於剛才的程序中沒有加入對郵件頭部信息和郵件體編碼的功能。一個典型的郵件頭是這個樣子:
From:″cxx″
To:
Subject: =?gb2312?B?taW797TLtKbK5MjrytW8/sjL?=
Date: Mon, 20 Dec 1999 16:46:58+0800
MIME-Version: 1.0
Content-Type: text/plain;
charset=″gb2312″
Content-Transfer-Encoding: quoted-printable
在這個郵件頭指定的編碼方式是quoted-printable,實際上,中國大部分服務器都支持8位編碼,所以無須再進行編碼。經過修改的程序段如下:
Sub Winsock1_DataArrival()
......
Case 354
Winsock1.SendData″From:″&txtFrom.Text&vbCrLf&″To:″&txtTo.Text&vbCrLf&″Subject:″&txtSubject.Text&vbCrLf&″Date:″&Now()
Winsock1.SendData″MIME-Version: 1.0″&vbCrLf&″Content-Type: text/plain;charset=″″gb2312″″″&vbCrLf&″Content-Transfer-Encoding: 8bit″&vbCrLf&vbCrLf
Winsock1.SendData txtContent.Text
Winsock1.SendData vbCrLf&″.″&vbCrLf
......
End Sub
到此為止,一個簡單的電子郵件軟件就編寫成功了。各位感興趣的讀者可以根據需要對功能進行增減,使其滿足自己的需要。