by Kamal A. Mehdi

Description

This sample code demonstrates how to use the Winsock control shipped with Visual Basic to send an email message through an SMTP (Simple Mail Transport Protocol) server. The sample code makes a connection with the SMTP remote host via TCP on port 25 and sends the email message data containing the sender name, sender email address, recipient name, recipient email address, message subject, and the message body text. It checks for the appropriate response code to be sent by the SMTP server in each data-segment transmission to verify that data is correctly received by the server.

The core of the code is represented by the SendEmail procedure, which is explained later in detail. The sample code will only send simple text email messages to SMTP mail servers; no attachments are possible.

Syntax

SendEmail(MailServerName, SenderName, SenderEmail, RecipientName,
ËRecipientEmail, EmailSubject, EmailBody)

Part Description

--------------------------------------------------------------------------------

MailServerName Required. A string expression specifying the name of the SMTP server.
SenderName Required. A string expression specifying the name of the email sender.
SenderEmail Required. A string expression specifying the email address of the sender.
RecipientName Required. A string expression specifying the name of the email recipient.
RecipientEmail Required. A string expression specifying the email address of the recipient.
EmailSubject Required. A string expression specifying the email message subject.
EmailBody Required. A string expression specifying the body of the message text.

--------------------------------------------------------------------------------


Modules and Controls Required

Module/Control Description

--------------------------------------------------------------------------------

Form1 A standard non-MDI Visual Basic form (.FRM) with the Caption property set to Send E-Mail Using the Winsock Control
Winsock1 A Winsock control
Command1 A command button with the Caption property set to &Send E-Mail
Command2 A command button with the Caption property set to &Exit
StatusLabel A label control with the Caption property set to gh
Frame1 A frame control with the Caption property set to Status:
Text1() A control array of seven text boxes with the Text1(6) MultiLine property set to True
Label1() A control array of seven label controls with the Caption property set as shown:
Index = Caption
0 = Your Name
1 = From (Your e-mail address)
2 = Recipientfs Name
3 = To (Recipientfs e-mail address)
4 = E-Mail (SMTP) server Name
5 = Subject
6 = Message Body

--------------------------------------------------------------------------------


Follow these steps to draw controls:

1. Start a new standard EXE project. Form1 is created by default. Set the formfs Height and Width properties to approximately 6100 and 7200, respectively, and set its Caption property as shown earlier in this section.
2. Draw Label1 on the top-left side of the form. Create the other six label control array elements from the label control and position them under Label1(0) so that they are arranged according to their Index property value (0, 1,..., 6 from top to bottom). Set the Caption property of each of the label control array elements as shown earlier.
3. Draw Text1 to the right of Label1(0). Create the other six text box control array elements from the text box and position them to the right of each label control created in step 2, with each text box to the right of the label control that has the same Index property value. Adjust the width of all text boxes so that they extend up to the right edge of the form. Adjust the height of the last text box (Text1(6)) so that it can accommodate multiple lines, and set its MultiLine property to True.
4. Draw Command1 and Command2 command buttons under Text1(6) and set their Caption properties as shown earlier.
5. Draw Frame1 below the command buttons and set its Caption property as shown earlier.
6. Draw the StatusLabel label control inside Frame1, and adjust its size so that it fills the entire frame area.
7. Draw the Winsock1 Winsock control anywhere on the form.


--------------------------------------------------------------------------------
Note
The Winsock control is not included on the toolbox by default. You can add it to the toolbox by selecting the Components submenu from the Project menu and adding the control.

You can create control arrays by inserting one control on the form and copying and pasting the control on the form using either the right mouse button or the Edit menu. When you paste the control on the form, Visual Basic will prompt you whether to create a control array; choose Yes.


--------------------------------------------------------------------------------

Code Listing

eGeneral form declarations
Dim Response As String

Sub SendEmail(MailServerName As String, SenderName As String,
Ë SenderEmailAddress As String, RecipientName As String,
Ë RecipientEmailAddress As String, EmailSubject As String,
Ë EmailBodyOfMessage As String)

eDeclare variables
Dim Data1 As String, Data2 As String
Dim Data3 As String, Data4 As String
Dim Data5 As String, Data6 As String
Dim Data7 As String, Data8 As String
Dim CurrentDate As String
Dim TimeDifference As String

eSet the Winsock controlfs local port to 0, because otherwise
eyou may not be able to send more than one e-mail message
eevery time the program runs
Winsock1.LocalPort = 0

eStart composing the required data strings, but first check
eif the Winsock socket is closed
If Winsock1.State = sckClosed Then

eCompose the current date and time string
TimeDifference = g -200h eYour zone time-difference

CurrentDate = Format(Date, gDddh) & g, g & Format(Date, gdd Mmm YYYYh)
Ë& g g & Format(Time, ghh:mm:ssh) & TimeDifference

eSet the program name used to send this e-mail message (you can
eput your program name here)
AppName = gX-Mailer: g + gMy Mail Program V1.0h + Chr(13) + Chr(10)

eSet the e-mail address of the sender
Data1 = gmail from:h + Chr(32) + SenderEmailAddress + Chr(13) +
ËChr(10)

eSet the e-mail address of the recipient
Data2 = grcpt to:h + Chr(32) + RecipientEmailAddress + Chr(13) +
ËChr(10)

eSet the date string
Data3 = gDate:h + Chr(32) + CurrentDate + Chr(13) + Chr(10)

eSet the name of the sender
Data4 = gFrom:h + Chr(32) + SenderName + Chr(13) + Chr(10)

eSet the name of the recipient
Data5 = gTo:h + Chr(32) + Text1(2) + Chr(13) + Chr(10)

eSet the subject of the E-Mail message
Data6 = gSubject:h + Chr(32) + EmailSubject + Chr(13) + Chr(10)

eSet the E-mail message body string
Data7 = EmailBodyOfMessage + Chr(13) + Chr(10)

eCombine the whole string for proper SMTP syntax
Data8 = Data4 + Data3 + AppName + Data5 + Data6

eSet the Winsock protocol
Winsock1.Protocol = sckTCPProtocol

eSet the remote host name (of SMTP server)
Winsock1.RemoteHost = MailServerName

eSet the SMTP Port to the default port 25
Winsock1.RemotePort = 25

eStart the connection
Winsock1.Connect

eWait for response from the remote host
WaitForResponse (g220h)

eReport status
StatusLabel.Caption = gConnecting....h
StatusLabel.Refresh

eSend your computer name or company name
Winsock1.SendData (gHELO mycomputernameh + Chr(13) + Chr(10))

eWait for response from the remote host
WaitForResponse (g250h)

eUpdate status
StatusLabel.Caption = gConnectedh
StatusLabel.Refresh

eSend the first string
Winsock1.SendData (Data1)

eUpdate status
StatusLabel.Caption = gSending Messageh
StatusLabel.Refresh

eWait for response from the remote host
WaitForResponse (g250h)

eSend the second string
Winsock1.SendData (Data2)

eWait for response from the remote host
WaitForResponse (g250h)

eTell the SMTP server that you want to send data now
Winsock1.SendData (gdatah + Chr(13) + Chr(10))

eWait for response from the remote host
WaitForResponse (g354h)

eSend the data
Winsock1.SendData (Data8 + Chr(13) + Chr(10))
Winsock1.SendData (Data7 + Chr(13) + Chr(10))
Winsock1.SendData (g.h + Chr(13) + Chr(10))

eWait for response from the remote host
WaitForResponse (g250h)

eSend quitting acknowledgment
Winsock1.SendData (gquith + Chr(13) + Chr(10))

eUpdate status
StatusLabel.Caption = gDisconnectingh
StatusLabel.Refresh

eWait for response from the remote host
WaitForResponse (g221h)

eClose the connection
Winsock1.Close

Else

eReport error
MsgBox (Str(Winsock1.State))

End If

End Sub

Sub WaitForResponse(ResponseCode As String)

Dim Start As Single
Dim TimeToWait As Single

Start = Timer

eStart a loop checking for response from SMTP host
While Len(Response) = 0

TimeToWait = Start - Timer
DoEvents
eIf TimeToWait expires, report timeout error

If TimeToWait > 50 Then
MsgBox gSMTP timeout error, no response receivedh, 64, App.Title
Exit Sub
End If

Wend

While Left(Response, 3) <> ResponseCode
DoEvents

If TimeToWait > 50 Then
eReport error if incorrect code is received
MsgBox gSMTP error, improper response code received!h + Chr(10) +
ËhCorrect code is: g + ResponseCode + g, Code received: g +
ËResponse, 64, App.Title
Exit Sub

End If

Wend

eSet response to nothing
Response = gh

End Sub

Private Sub Command1_Click()

eCall the SendEmail procedure and pass the arguments: MailServerName,
e SenderName, SenderEmailAddress, RecipientName, RecipientEmailAddress,
e EmailSubject, EmailBodyOfMessage)
SendEmail Text1(4), Text1(0), Text1(1), Text1(2), Text1(3), Text1(5),
ËText1(6)

eUpdate status
StatusLabel.Caption = gMail Senth
StatusLabel.Refresh

End Sub

Private Sub Command2_Click()

Unload Me

End Sub

Private Sub Form_Unload(Cancel As Integer)

Set Form1 = Nothing

End

End Sub

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)

eCheck for response from the remote host
Winsock1.GetData Response

End Sub

Enter the code into the appropriate form or control events as indicated, and run the project. Fill the text boxes with the appropriate data and click the Send E-Mail button. Watch the status label for the email session progress.

Analysis

The SendEmail procedure uses the Winsock control to send a simple plain text email message to an SMTP mail server. The use of the procedure is simple: you just need to send the necessary email message data as arguments, including the sender name, sender email address, recipientfs name and email address, and the email message subject and body text.

The SendEmail procedure starts the email session by composing the necessary email message data segments, initializing the Winsock control, connecting to the SMTP remote server, sending the senderfs and recipientfs email addresses, transferring the message data, and disconnecting from the remote server and closing the session. In each step of the email session, the SendEmail procedure calls another procedure, WaitForResponse, which checks the response code received from the remote server to verify whether the response is correct.

While the SendEmail procedure sends the email message, it updates a status label with the progress of the entire process. It reports the status when it first starts to connect to the remote host, when it gets connected, when the message is successfully sent, and when it disconnects. It also displays a message box when an error occurs during the email transfer process, such as a server reply time out, incorrect response code received from the SMTP server, and so on. It also displays a message box if the user tries to send an email while the Winsock socket is still open from a previous email session.