📄 39.txt
字号:
简单电子邮件发送程序
本文将向你介绍如何编写一个能发送简单的电子邮件的程序。所谓简单是指本程序只能发送纯文本,并且一次只能发送给一个收件人。
首先新建一个工程。
将窗体的Name属性改为"frmSendMail" ,Caption属性改为"Simple Mail sender", BorderStyle 属性值设为"1 - Fixed Single"。
向窗体中添加一个Winsock控件。按下图所示在窗体中添加相应的控件。
将上面的New Message, Send Message ?Close 等命令按钮的Name属性分别改为cmdNew, cmdSend ?及cmdClose。
将下面的代码添加到相应的事件中
Private Sub cmdNew_Click()
txtRecipient = ""
txtSubject = ""
txtMessage = ""
End Sub
Private Sub cmdClose_Click()
Unload Me
End Sub
现在来写发送邮件的代码。
如果你看过本站的上一篇文章“SMTP协议简介”的话,你就已经知道了我们在这里会用到一些什么样的命令。这些命令必须严格按照预先规定的顺序来发送。为了跟踪这一顺序,我们将用到一个特殊的变量m_State,我们将用它来存储当前的SMTP进程的状态。
你可以将SMTP进程状态看作是等待服务对某一命令反应的状态,也就是说向服务器发送了多少个命令就有多少个状态。我们无法用VB的数据类型来描述进程所处的状态。因此本程序中用到了一个特殊的数据类型"SMTP_State" 。把下面的代码添加到窗体的声明段中:
Private Enum SMTP_State
MAIL_CONNECT
MAIL_HELO
MAIL_FROM
MAIL_RCPTTO
MAIL_DATA
MAIL_DOT
MAIL_QUIT
End Enum
Private m_State As SMTP_State
把下面的代码放在Send Message的Click事件中。
Private Sub cmdSend_Click()
Winsock1.Connect Trim$(txtHost), 25
m_State = MAIL_CONNECT
End Sub
上面的代码第一行用来同服务器建立连接,25是SMTP服务器的默认端口号。接下来要做的就是在Winsock的DataArrival事件中编写代码处理服务的回应。代码的结构如下:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim strServerResponse As String
Dim strResponseCode As String
strResponseCode = Left(strServerResponse, 3)
If strData = "250" Or _
strData = "220" Or _
strData = "354" Then
Select Case m_State
Case MAIL_CONNECT
Case MAIL_HELO
Case MAIL_FROM
Case MAIL_RCPTTO
Case MAIL_DATA
Case MAIL_DOT
Case MAIL_QUIT
End Select
Else
MsgBox "SMTP Error: " & strServerResponse, _
vbInformation, "SMTP Error"
End If
End Sub
第一行执行代码用来辨明来自服务器的回应。接下来的IF/ELSE/ENDIF循环用来判断回应是否同预定义的值相等。220,250和354都是来自服务器的肯定回应(详见SMTP协议简介一文),对于来自服务器的失败的回应则用一个对话框来显示。下面是完整的代码。
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim strServerResponse As String
Dim strResponseCode As String
Dim strDataToSend As String
'
'接收来自服务器的数据并存储在strServerResponse变量中
'
Winsock1.GetData strServerResponse
'
Debug.Print strServerResponse
'
获取来自服务器的回应的代码
'
strResponseCode = Left(strServerResponse, 3)
'
'只有下面这个三个数字才表示服务执行你的命令成功,我们可以进行下一步的操作
'
If strResponseCode = "250" Or _
strResponseCode = "220" Or _
strResponseCode = "354" Then
Select Case m_State
Case MAIL_CONNECT
'改变当前进程的状态
m_State = MAIL_HELO
'
'去掉空格
strDataToSend = Trim$(txtSender)
'
'获取信箱名
strDataToSend = Left$(strDataToSend, _
InStr(1, strDataToSend, _
"@") - 1)
'向服务器发送HELO命令
Winsock1.SendData "HELO " & _
strDataToSend & vbCrLf
'
Debug.Print "HELO " & strDataToSend
'
Case MAIL_HELO
'
'改变当前进程的状态
m_State = MAIL_FROM
'
'向服务器发送 MAIL FROM命令
Winsock1.SendData "MAIL FROM:" & _
Trim$(txtSender) & vbCrLf
'
Debug.Print "MAIL FROM:" & Trim$(txtSender)
'
Case MAIL_FROM
'
'改变当前进程的状态
m_State = MAIL_RCPTTO
'
'
Winsock1.SendData "RCPT TO:" & _
Trim$(txtRecipient) & vbCrLf
'
Debug.Print "RCPT TO:" & Trim$(txtRecipient)
'
Case MAIL_RCPTTO
'
'改变当前进程的状态
m_State = MAIL_DATA
'
'向服务器发送DATA命令
Winsock1.SendData "DATA" & vbCrLf
'
Debug.Print "DATA"
'
Case MAIL_DATA
'
'改变当前进程的状态
m_State = MAIL_DOT
'
'现在我们可以开始发送邮件正文
'文本的每一行必须以vbLf结尾
'记住不是vbCrLf
'
'发送邮件主题
Winsock1.SendData "Subject:" & txtSubject & vbLf
'
Debug.Print "Subject:" & txtSubject
'
Dim varLines As Variant
Dim varLine As Variant
'
'解析邮件以获得行(VB6适用)
varLines = Split(txtMessage, vbCrLf)
'
'发送每一行邮件
For Each varLine In varLines
Winsock1.SendData CStr(varLine) & vbLf
'
Debug.Print CStr(varLine)
Next
'
'向服务器发送一个小数点告诉服务器邮件发送完毕。
Winsock1.SendData "." & vbCrLf
'
Debug.Print "."
'
Case MAIL_DOT
'改变当前进程的状态
m_State = MAIL_QUIT
'
'向服务器发送QUIT命令
Winsock1.SendData "QUIT" & vbCrLf
'
Debug.Print "QUIT"
Case MAIL_QUIT
'
'断开连接
Winsock1.Close
'
End Select
Else
'
'如果服务器返回一个错误的代码就断开连接并提示用户
'
Winsock1.Close
'
MsgBox "SMTP Error: " & strServerResponse, _
vbInformation, "SMTP Error"
'
End If
End Sub
请注意,对于要发送的文本,我们是以vbLf结尾,而不是vbCrLf。这一规则同样适用于发送邮件的主题。如果不以vbLf结尾会让服务器错误理解你的命令。最后要做的事是对Winsock的Error事件编码,以处理错误。
Private Sub Winsock1_Error(ByVal Number As Integer, _
Description As String, _
ByVal Scode As Long, _
ByVal Source As String, _
ByVal HelpFile As String, _
ByVal HelpContext As Long, _
CancelDisplay As Boolean)
MsgBox "Winsock Error number " & Number & vbCrLf & _
Description, vbExclamation, "Winsock Error"
End Sub
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -