Click here to Skip to main content
16,012,168 members
Articles / Programming Languages / Visual Basic
Article

How to send a simple text email message

Rate me:
Please Sign up or sign in to vote.
3.97/5 (26 votes)
14 Nov 20042 min read 238K   1.3K   58   58
How to send a simple text email message.

Sample Image - IndySMTP.gif

Introduction

This article will provide a very basic overview of how to send a plain text mail message with the open source Indy sockets library for .NET.

Constructing the Message

The following code is the basic structure for constructing a message:

C#
C#
Indy.Sockets.Message LMsg = new Indy.Sockets.Message();
LMsg.From.Text = textFrom.Text.Trim();
LMsg.Recipients.Add().Text = textTo.Text.Trim();
LMsg.Subject = textSubject.Text.Trim();
LMsg.Body.Text = textMsg.Text;

Visual Basic

VB.NET
Dim LMsg As New Indy.Sockets.Message
LMsg.From.Text = textFrom.Text.Trim
LMsg.Recipients.Add.Text = textTo.Text.Trim
LMsg.Subject = textSubject.Text.Trim
LMsg.Body.Text = textMsg.Text

A call to the Clear method is necessary only if a single Message is being reused. Clear resets the message content and other fields to their default or empty states.

It is actually legal to send messages without From, Subject, and Body. However, such a message is not very useful and many servers will reject it either as faulty, or probable spam. Thus, these properties should be considered the minimum requirements for sending a message.

For more advanced messages, the Message class also has properties for CC, BCC, Attachments, HTML and more.

Sending the Message

Once a message has been constructed, it must be delivered to an SMTP server. This is done using the SMTP class. The following code is the basic form for sending a message:

C#

C#
SMTP LSMTP = new SMTP();
LSMTP.Host = textSMTPServer.Text.Trim();
LSMTP.Connect();
try {
  LSMTP.Send(LMsg);
  Status("Completed");
}
finally {
  LSMTP.Disconnect();
}

Visual Basic

VB.NET
Dim LSMTP As New SMTP
LSMTP.Host = textSMTPServer.Text.Trim
LSMTP.Connect()
Try
  LSMTP.Send(LMsg)
  'Status("Completed")
Finally
  LSMTP.Disconnect()
End Try

The host must be set so that the SMTP class knows where to send the messages to. In the case of SMTP, the host can be thought of as the address of the local post office.

The Send method accepts one argument which specifies the Message class to send.

In this example, only one message is sent. However, the SMTP protocol allows for multiple messages, so it is not necessary to connect and disconnect if multiple messages are to be sent. To send multiple messages, simply make additional calls to the Send method while connected. Multiple Message instances can be used, or an existing one can be modified between calls to Send.

Send Mail Demo

A very basic demo of sending a simple mail message is available as SendMail.

In addition to the basics covered in this article, the demo also makes use of the OnStatus event. The OnStatus event is a core event of Indy but implemented differently by each protocol. OnStatus is fired at various times during calls to Connect, Send, and Disconnect. Each time, a text message is passed that explains what is occurring. OnStatus is designed to provide user interface updates, or logging. It's not designed for pragmatic interpretation of state. In the SendMail demo, the messages from OnStatus are displayed into a ListBox.

In this demo, the OnStatus event has been defined as follows:

C#

C#
private void Status(string AMessage) {
  lboxStatus.Items.Add(AMessage);
  // Allow the listbox to repaint
  Application.DoEvents();
  Application.DoEvents();
  Application.DoEvents();
}

private void SMTPStatus(object aSender, Status aStatus, string aText) {
  Status(aText);
}

Visual Basic

VB.NET
Private Sub Status(ByVal aMessage As String)
  lboxStatus.Items.Add(aMessage)
  ' Allow the listbox to repaint
  Application.DoEvents()
  Application.DoEvents()
  Application.DoEvents()
End Sub

Private Sub SMTPStatus(ByVal aSender As Object, ByVal aStatus As Status, 
  ByVal aText As String)
  Status(aText)
End Sub

When the Send Mail button is pressed, the following code is executed to send the message:

C#

C#
private void butnSendMail_Click(object sender, System.EventArgs e)  {
  butnSendMail.Enabled = false; 
  try {
    Indy.Sockets.Message LMsg = new Indy.Sockets.Message();
    LMsg.From.Text = textFrom.Text.Trim();
    LMsg.Recipients.Add().Text = textTo.Text.Trim();
    LMsg.Subject = textSubject.Text.Trim();
    LMsg.Body.Text = textMsg.Text;

    // Attachment example
    // new AttachmentFile(LMsg.MessageParts, @"c:\temp\Hydroponics.txt");

    SMTP LSMTP = new SMTP();
    LSMTP.OnStatus += new Indy.Sockets.TIdStatusEvent(SMTPStatus);
    LSMTP.Host = textSMTPServer.Text.Trim();
    LSMTP.Connect();
    try {
      LSMTP.Send(LMsg);
      Status("Completed");
    }
    finally {
      LSMTP.Disconnect();
    }
  }
  finally {
    butnSendMail.Enabled = true;
  }
}

Visual Basic

VB.NET
Private Sub butnSendMail_Click(ByVal sender As System.Object, 
  ByVal e As System.EventArgs) Handles butnSendMail.Click
  butnSendMail.Enabled = False
  Try
    Dim LMsg As New Indy.Sockets.Message
    LMsg.From.Text = textFrom.Text.Trim
    LMsg.Recipients.Add.Text = textTo.Text.Trim
    LMsg.Subject = textSubject.Text.Trim
    LMsg.Body.Text = textMsg.Text

    ' Attachment example
    ' Dim xAttachment As New AttachmentFile(
    '    LMsg.MessageParts, "c:\temp\Hydroponics.txt")

    Dim LSMTP As New SMTP
    AddHandler LSMTP.OnStatus, AddressOf SMTPStatus
    LSMTP.Host = textSMTPServer.Text.Trim
    LSMTP.Connect()
    Try
      LSMTP.Send(LMsg)
      'Status("Completed")
    Finally
      LSMTP.Disconnect()
    End Try
  Finally
    butnSendMail.Enabled = True
  End Try
End Sub

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Cyprus Cyprus
Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"

I am a former Microsoft Regional DPE (MEA) covering 85 countries, former Microsoft Regional Director, and 10 Year Microsoft MVP.

I have lived in Bulgaria, Canada, Cyprus, Switzerland, France, Jordan, Russia, Turkey, The Caribbean, and USA.

Creator of Indy, IntraWeb, COSMOS, X#, CrossTalk, and more.

Comments and Discussions

 
GeneralSubject in email header Pin
purse0017-Jul-05 20:51
purse0017-Jul-05 20:51 
GeneralRe: Subject in email header Pin
Chad Z. Hower aka Kudzu8-Jul-05 3:38
Chad Z. Hower aka Kudzu8-Jul-05 3:38 
GeneralRe: Subject in email header Pin
purse0018-Jul-05 3:59
purse0018-Jul-05 3:59 
QuestionPorts? Pin
Anonymous24-Jun-05 5:58
Anonymous24-Jun-05 5:58 
AnswerRe: Ports? Pin
Chad Z. Hower aka Kudzu25-Jun-05 2:59
Chad Z. Hower aka Kudzu25-Jun-05 2:59 
GeneralMultiPart Message Pin
Jay Dubal17-May-05 18:36
Jay Dubal17-May-05 18:36 
GeneralRe: MultiPart Message Pin
Chad Z. Hower aka Kudzu17-May-05 22:31
Chad Z. Hower aka Kudzu17-May-05 22:31 
GeneralSome questions about Indy Pin
Marc Clifton19-Jan-05 14:27
mvaMarc Clifton19-Jan-05 14:27 
Hi,

Nice article. I've been playing with Indy and I came up with some questions which I hope you don't mind answering.

It seems that Indy's TCPClient/TCPServer is noticeably slower than .NET's TcpClient implementation. And I'm talking about just using it on an intranet in a controlled environment. Have you noticed performance problems with Indy and .NET? If not, are there some general guidelines as to how to configure Indy for optimal performance?

The OnExecute event seems to be the only event that can be used for handling data being received, but it acts different than I expected. As soon as the connection is established, the OnExecute event fires, which goes into my code which implements a IOHandler.Read method, which of course doesn't return until data is actually sent to the server. Is this by design?

Regarding the OnExecute above, in my test application, the client connects to the server and sends a packet, the server responds with a packet and then the client disconnects. But because the OnExecute gets called again, when the client disconnects Indy throws the "connection closed gracefully" exception in the read method. This seems very wasteful. Exceptions in .NET are time consuming. Any thoughts on how I should properly implement the described client-server-client flow?

Again, regarding the OnExecute event, and the event handler performs a Write operation, are other events blocked from firing from other connections? I would assume not, but I'm a bit suspicious of this.

Are streams ever shared/re-used among connections? I was getting some odd behavior that made me wonder about this, but it was probably my code. Especially the re-use of streams concerns me--are streams ever being re-used?

Is there any documentation that actually describes what the methods, properties, and events do? I've read through Indy In Depth, and frankly, it's pretty shallow.

I'd like to eventually write an article about Indy and my experiences, but right now I'm on the fence as to whether I would recommend it to others or not.

Thanks!

Marc

MyXaml
Advanced Unit Testing
YAPO
GeneralRe: Some questions about Indy Pin
Chad Z. Hower aka Kudzu2-Jul-05 10:49
Chad Z. Hower aka Kudzu2-Jul-05 10:49 
GeneralCode did not work due to the following error... Pin
serdar baser3-Jan-05 22:01
serdar baser3-Jan-05 22:01 
GeneralRe: Code did not work due to the following error... Pin
Chad Z. Hower aka Kudzu4-Jan-05 1:53
Chad Z. Hower aka Kudzu4-Jan-05 1:53 
GeneralRe: Code did not work due to the following error... Pin
serdar baser4-Jan-05 3:01
serdar baser4-Jan-05 3:01 
GeneralRe: Code did not work due to the following error... Pin
Chad Z. Hower aka Kudzu6-Jan-05 15:55
Chad Z. Hower aka Kudzu6-Jan-05 15:55 
GeneralLicensing of Borland components Pin
mmirko20-Dec-04 23:22
mmirko20-Dec-04 23:22 
GeneralRe: Licensing of Borland components Pin
Chad Z. Hower aka Kudzu21-Dec-04 5:00
Chad Z. Hower aka Kudzu21-Dec-04 5:00 
QuestionIs Borland.Vcl needed? Pin
Theo Bebekis15-Nov-04 21:47
Theo Bebekis15-Nov-04 21:47 
AnswerRe: Is Borland.Vcl needed? Pin
Chad Z. Hower aka Kudzu16-Nov-04 5:01
Chad Z. Hower aka Kudzu16-Nov-04 5:01 
AnswerRe: Is Borland.Vcl needed? Pin
Matthijs ter Woord5-Oct-06 21:08
Matthijs ter Woord5-Oct-06 21:08 
QuestionDoes/will it support S/MIME? Pin
MadSi14-Nov-04 23:30
sussMadSi14-Nov-04 23:30 
AnswerRe: Does/will it support S/MIME? Pin
Chad Z. Hower aka Kudzu16-Nov-04 5:03
Chad Z. Hower aka Kudzu16-Nov-04 5:03 
GeneralRead email message with Indy Pin
Alf1321-Jul-04 9:00
Alf1321-Jul-04 9:00 
GeneralRe: Read email message with Indy Pin
Chad Z. Hower aka Kudzu14-Nov-04 10:48
Chad Z. Hower aka Kudzu14-Nov-04 10:48 
GeneralSuppose ESMTP won't work... Pin
chaos081527-May-04 10:50
chaos081527-May-04 10:50 
GeneralRe: Suppose ESMTP won't work... Pin
Chad Z. Hower aka Kudzu28-May-04 11:18
Chad Z. Hower aka Kudzu28-May-04 11:18 
QuestionHow to add attachments? Pin
JasperB27-May-04 3:20
JasperB27-May-04 3:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.