面對 Outlook Express、Foxmail 等成熟郵件軟體,你是否想過親手寫一個?本文將帶你從 TELNET 手動發信理解 SMTP 協議,再以 Visual Basic 6.0 搭配 Winsock 控件,一步步打造屬於自己的簡易郵件發送程式。
在寫代碼前,先搞懂伺服器真正在跑什麼。
telnet.exe,「終端機」→「偏好設定」開啟「本地回顯」。smtp.example.com),連接埠填 25。220 歡迎代碼。HELO yourhostname → 回 250MAIL FROM:<your@email.com> → 回 250RCPT TO:<recipient@email.com> → 回 250(可重複多位收件者)DATA → 回 354,開始輸入郵件內容. → 回 250QUIT → 回 221 斷線關鍵點:每個指令後必須檢查伺服器回應代碼,才能決定下一步動作。
Winsock1) 到表單,屬性設定:
LocalPort = 25RemotePort = 25Protocol = 0 (sckTCPProtocol)RemoteHost 執行時由使用者輸入伺服器位址指定txtServer、txtFrom、txtTo、txtSubject、txtContent,按鈕 cmdSend。利用 Winsock1_DataArrival 事件接收資料,配合表單 Tag 屬性記錄當前指令階段。
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 ' 連線成功
Tag = "helo"
Winsock1.SendData "helo " & txtServer.Text & vbCrLf
Case 250 ' 指令接受
Select Case Tag
Case "helo"
Winsock1.SendData "mail from:" & txtFrom.Text & vbCrLf
Tag = "mail"
Case "mail"
Winsock1.SendData "rcpt to:" & txtTo.Text & vbCrLf
Tag = "rcpt"
Case "rcpt"
Winsock1.SendData "data" & vbCrLf
Tag = "data"
Case "data"
Winsock1.SendData "quit" & vbCrLf
Tag = "quit"
End Select
Case 354 ' 進入資料模式
' 發送郵件標頭與內容
Winsock1.SendData "From:" & txtFrom.Text & vbCrLf & _
"To:" & txtTo.Text & vbCrLf & _
"Subject:" & txtSubject.Text & vbCrLf & _
"Date:" & Format(Now, "ddd, dd mmm yyyy hh:nn:ss") & vbCrLf & _
"MIME-Version: 1.0" & vbCrLf & _
"Content-Type: text/plain; charset=""big5""" & vbCrLf & _
"Content-Transfer-Encoding: 8bit" & vbCrLf & vbCrLf
Winsock1.SendData txtContent.Text
Winsock1.SendData vbCrLf & "." & vbCrLf
Case 221 ' 結束
Tag = ""
Case Else
Winsock1.SendData "quit" & vbCrLf
Tag = "quit"
MsgBox "錯誤: " & Data
End Select
End Sub
初版程式缺少標頭導致收件端無法正確顯示寄件者、主題、日期。標準郵件標頭範例:
From: "sender"
To: "recipient"
Subject: =?big5?B?encoded_subject?=
Date: Mon, 20 Dec 1999 16:46:58 +0800
MIME-Version: 1.0
Content-Type: text/plain; charset="big5"
Content-Transfer-Encoding: 8bit
中文環境下,大多數伺服器支援 8bit 傳輸,無需 Quoted-Printable 編碼。將 Case 354 區塊替換為上方標頭組裝代碼即可。主題若含中文,建議採用 MIME Base64 編碼(=?big5?B?...?=),VB 可用 StrConv + 自製 Base64 函式處理。
透過親手實作 SMTP 用戶端,不僅能深入理解郵件傳輸核心機制,更能靈活客製化發信邏輯(如批次發送、自動化報表郵寄)。雖然現代開發多改用 .NET System.Net.Mail 或成熟函式庫,但這份「從零開始」的經驗,是通往網路程式設計殿堂的紮實基石。