This time I will provide a basic introduction to the SMTP protocol and show some demo code in C# and Delphi. All code uses Indy which is open source and available at http://www.IndyProject.org/. For existing Indy users, please note that demos are built for Indy 10.
What is SMTP?
SMTP is the Simple Mail Transport Protocol. SMTP is used only for sending mail, not for receiving. To receive mail, another protocol such as POP3 or IMAP4, must be used.
SMTP clients typically deliver all mail to a single SMTP server and let the SMTP server decide the final destination
How does SMTP work?
An SMTP client accepts messages that it transmits to a known SMTP server. This server then determines where the messages actually should be delivered to and then relays each individual message to local mailboxes, or other SMTP servers. SMTP clients typically deliver all mail to a single SMTP server and let the SMTP server decide the final destination.
The SMTP server is like your local post office. You can use other post offices, but if you have mail for many different destinations it is much easier to give it to the local post office to let them sort it and deliver it to the destination post office rather than going to each post office yourself.
Fig.1: Indy SMTP Support
Indy has robust SMTP support. However, in this installment only the basics will be covered of sending a basic text mail message. To send a mail message with Indy two components are needed: TIdSMTP and TIdMessage.
TIdSMTP
TIdSMTP is the Indy component that connects and communicates with a SMTP server.
TIdMessage
TIdSMTP only handles the communication. TIdMessage handles all the semantics of storing, encoding and decoding messages and message parts. Message parts consist of headers, HTML, file attachments, and more.
TIdMessage is separate from TIdSMTP not only because of encapsulation, but because several other protocols such as POP3 and NNTP use the same message formats and TIdMessage thus is a common component.
TIdMessage also supports methods for storing and loading messages from streams and files.
Constructing the Message
The following code is the basic structure for constructing a message:
C#
Indy.Sockets.IndyMessage.Message LMsg =
  new Indy.Sockets.IndyMessage.Message();
LMsg.From.Text = AFrom;
LMsg.Recipients.Add().Text = ATo;
LMsg.Subject = ASubject;
LMsg.Body.Text = AMsg;
Delphi
with mesgMessage do
begin
 Clear;
 From.Text := AFrom;
 Recipients.Add.Text := ATo;
 Subject := ASubject;
 Body.Text := AMsg;
end;
A call to the Clear method is necessary only if a single TIdMessage 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 either faulty, or probable spam. Thus these properties should be considered the minimum requirements for sending a message.
For more advanced messages TIdMessage 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 TIdSMTP. The following code is the basic form for sending a message:
C#
SMTP LSMTP = new SMTP();
LSMTP.Host = "mail.mycompany.com";
LSMTP.Connect();
try {
 LSMTP.Send(LMsg);
}
finally {
 LSMTP.Disconnect();
}
Delphi
with smtpSendMail do
begin
 Host := 'mail.mycompany.com';
 Connect;
 try
   Send(mesgMessage);
 finally
   Disconnect;
 end;
end;
The host must be set so that the TIdSMTP 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 TIdMessage 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 TIdMessage components can be used, or an existing one can be modified between calls to Send.
QuickSend
When only one message needs to be sent, and the message is a basic text message a simpler but more limited form is available. QuickSend is a class method of TIdSMTP. No TIdMessages, or even a TIdSMTP needs to be created.
QuickSend constructs a TIdMessage, TIdSMTP and performs all necessary communication with an SMTP server including connection and disconnection.
The declaration of QuickSend is as follows:
class procedure QuickSend(const AHost,
                               ASubject,
                               ATo,
                               AFrom,
                               AText: string);
A sample is:
C#
SMTP.QuickSend(null, "mail.mycompany.com",
                    "Message from me",
                    "you@yourcompany.com",
                    "me@mycompany.com",
                    "Hello! I am sending you mail.");
Delphi
TIdSMTP.QuickSend('mail.mycompany.com',
                 'Message from me',
                 'you@yourcompany.com',
                 'me@mycompany.com',
                 'Hello! I am sending you mail.');
Be sure to note that this is a class method. You do not need to create an instance of TIdSMTP. Instead the method is called as part of the class itself.
Send Mail Demo
A very basic demo of sending a simple mail message is available as SendMail.
Fig. 2: A Send Mail message
In addition to the basics covered in this chapter, 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 its not designed for programmatic interpretation of state. In the SendMail demo, the messages from OnStatus are displayed into a listbox.
In this demo the OnStatus even has been defined at design time and is as follows:
C#
private void Status(string AMessage) {
 lboxStatus.Items.Add(AMessage);
 // Allow the listbox to repaint
 Application.DoEvents();
 Application.DoEvents();
 Application.DoEvents();
}
<>void SMTPStatus(object ASender,
   Indy.Sockets.IndyComponent.Status AStatus,
   string AText)
{
 Status(AText);
}
Delphi
procedure TformMain.smtpSendMailStatus(ASender: TObject;
 const AStatus: TIdStatus; const AStatusText: String);
begin
 Status(AStatusText);
end;
procedure TformMain.Status(AMsg: string);
begin
 lboxStatus.ItemIndex := lboxStatus.Items.Add(AMsg);
 // Allow the listbox to repaint
 Application.ProcessMessages;
 Application.ProcessMessages;
 Application.ProcessMessages;
end;
When the Send Mail button is pressed the following code is executed to send the message:
C#
private void butnSendMail_Click(object sender,
 System.EventArgs e)
 {
 butnSendMail.Enabled = false;
 try {
   Indy.Sockets.IndyMessage.Message LMsg = new
      Indy.Sockets.IndyMessage.Message();
   LMsg.From.Text = textFrom.Text.Trim();
   LMsg.Recipients.Add().Text = textTo.Text.Trim();
   LMsg.Subject = textSubject.Text.Trim();
   LMsg.Body.Text = textMsg.Text;
   SMTP LSMTP = new SMTP();
   LSMTP.OnStatus += new
    Indy.Sockets.IndyComponent.TIdStatusEvent(
      SMTPStatus);
   LSMTP.Host = textSMTPServer.Text.Trim();
   LSMTP.Connect();
   try {
     LSMTP.Send(LMsg);
     Status("Completed");
   }
   finally {
     LSMTP.Disconnect();
   }
 }
 finally {
   butnSendMail.Enabled = true;
 }
}
Delphi
procedure TformMain.butnSendMailClick(Sender: TObject);
begin
 butnSendMail.Enabled := False; try
   with mesgMessage do begin
     Clear;
     From.Text := Trim(editFrom.Text);
     Recipients.Add.Text := Trim(editTo.Text);
     Subject := Trim(editSubject.Text);
     Body.Assign(memoMsg.Lines);
   end;
   with smtpSendMail do begin
     Host := Trim(editSMTPServer.Text);
     Connect; try
       Send(mesgMessage);
     finally Disconnect; end;
   end;
   Status('Completed');
 finally butnSendMail.Enabled := True; end;
end;
More Information
The demos can be downloaded in a complete ZIP archive from the Indy Demo Playground at http://www.atozed.com/Indy/.
·   Atozed Indy Portal - http://www.atozed.com/Indy/
·   Indy Website - http://www.indyproject.org/
·   RFC 2821 - Simple Mail Transfer Protocol - ftp://ftp.rfc-editor.org/in-notes/rfc2821.txt