POP3 Tutorial
Applies to: Rebex Total Pack, Rebex Mail Pack, Rebex POP3
Table of content
- Namespaces and assemblies
- POP3 basics - connecting, logging in and disconnecting
- Authenticating to a POP3 server
- Authentication using NTLM
- Obtaining info about the mailbox
- Sequence numbers and unique IDs
- Retrieving the message list
- Downloading message headers
- Downloading messages
- Deleting and undeleting messages
- Using events and logging communication
Namespaces and assemblies
There are several assemblies which have to be reference in your project to be
able to use all features of Mail for .NET described here. Rebex.Pop3.dll
is needed for any POP3 operations and contains the Pop3
class and others in
Rebex.Net namespace. Rebex.Mail.dll contains classes that make it possible
to read, create and write e-mail messages in MIME format and contains the MailMessage
class in Rebex.Mail namespace and a number of classes that represent mail message headers
in Rebex.Mime.Headers namespace.Rebex.Common.dll and Rebex.Networking.dll
need to be referenced too as assembly referenced by Rebex.Pop3.dll and
Rebex.Mail.dll .
To gain access to all described functionality, reference the two assemblies from your project and import the following namespaces in your source files:
using Rebex.Net; using Rebex.Mail; using Rebex.Mime.Headers;
Imports Rebex.Net Imports Rebex.Mail Imports Rebex.Mime.Headers
POP3 basics - connecting, logging in and disconnecting
Typical POP3 session goes like this:
- Connect to the POP3 server
- Login - authenticate with user name and password
- Work with messages in your mailbox
- Disconnect
POP3 is basically a single-session and single-folder protocol. While you are connected and authenticated,
you are not going to be informed when any new message arrives, and you only have access
to messages that were available at the time of authentication. Because of this, many
POP3 servers only allow a single session for a single account at a time, so don't forget
to call Disconnect
method when you are done with the mailbox, or you might
experience problems connecting again until the previous session either expires or the Ftp
object is claimed by .NET's garbage collector. Also, due to the nature of the POP3 protocol,
you will need to connect periodically if you wish to check for new messages.
And now let's look at some sample code.
// create client and connect Pop3 client = new Pop3(); client.Connect("pop3.example.org"); // authenticate client.Login("username", "password"); // work with messages //... // disconnect client.Disconnect();
'create client and connect Dim client As New Pop3 client.Connect("pop3.example.org") 'authenticate client.Login("username", "password") 'work with messages '... 'disconnect client.Disconnect()
Authenticating to a POP3 server
The POP3 protocol supports several authentication methods.
Normally, you just have to supply your credentials to the Login
method.
The library will automatically choose the best (most secure) authentication method
available and log you in.
Additionally, you can retrieve the list of supported authentication methods using
the Pop3
object's GetSupportedAuthenticationMethods
method, and specify
which one is to be used for login. (Or specify Pop3Authentication.Auto
that will
do this automatically.)
Pop3 client = new Pop3(); client.Connect("pop3.example.org"); // authenticate - let the library choose the best method client.Login("username", "password"); // or choose one yourself // client.Login("username", "password", Pop3Authentication.Plain);
'create client and connect Dim client As New Pop3 client.Connect("pop3.example.org") 'authenticate - let the library choose the best method client.Login("username", "password") 'or choose one yourself 'client.Login("username", "password", Pop3Authentication.Plain)
Authentication using NTLM
By default, the Login
method won't try NTLM authentication, because
it might not work correctly in some situations. However, if NTLM does work with your server,
nothing stops you from using it. Just read the information on Microsoft
Exchange
in the FAQ first if you use that server.
// create client and connect Pop3 client = new Pop3(); client.Connect("pop3.example.org"); // authenticate using NTLM client.Login("domain\\username", "password", Pop3Authentication.Ntlm);
' create client and connect Dim client As New Pop3() client.Connect("pop3.example.org") 'authenticate using NTLM client.Login("domain\username", "password", SmtpAuthentication.Ntlm)
NTLM also makes it possible to authenticate as the user under whose context your application is running. This makes it possible for the user to log in without the need to specify his or her password.
// create client and connect Pop3 client = new Pop3(); client.Connect("pop3.example.org"); // authenticate using NTLM client.Login(Pop3Authentication.Ntlm);
' create client and connect Dim client As New Pop3() client.Connect("pop3.example.org") ' authenticate using NTLM's single-sign-on feature client.Login(SmtpAuthentication.Ntlm)
Obtaining info about the mailbox
There are two pieces of information available - the number of messages in the mailbox
can be obtained using the GetMessageCount
method and the total size of them
using the GetMailboxSize
method.
// create client, connect and log in Pop3 client = new Pop3(); client.Connect("pop3.example.org"); client.Login("username", "password"); Console.Write("Number of messages in the mailbox is: "); Console.Write(client.GetMessageCount()); Console.WriteLine(); client.Disconnect();
'create client, connect and log in Dim client As New Pop3 client.Connect("pop3.example.org") client.Login("username", "password") Console.Write("Number of messages in the mailbox is: ") Console.Write(client.GetMessageCount()) Console.WriteLine() client.Disconnect()
Sequence numbers and unique IDs
The POP3 protocol uses two different IDs to identify messages.
ID type | Description |
---|---|
int sequenceNumber
|
A number between 1..[number of messages in the POP3 mailbox]. This number does not change during POP3 session - even when one or more messages are deleted, the remaining messages retaing their sequence number. However, these numbers are specific to a single session - when you disconnect and log in again later, the same sequence numbers will be assigned to different messages. |
string uniqueID
|
Unlike sequence number, the message unique ID is permanent and does not change between sessions. A message will retain its unique ID until it is deleted. |
Most POP3 methods that deal with messages only accept sequenceNumber
as a parameter
for message identification. However, it is quite simple to map a given unique ID to a corresponding
sequence number and vice-versa. Just retrieve the message list using use GetMessageList
method, use its Find method to get info about the given message and read its UniqueId
or SequenceNumber
properties to get the required ID.
string localPath = ""; // some valid unique ID we already retrieved in past string uniqueId = "abcd13954986"; // create client, connect and log in Pop3 client = new Pop3(); client.Connect("pop3.example.org"); client.Login("username", "password"); // get message list Pop3MessageCollection messages = client.GetMessageList(); Pop3MessageInfo info = messages.Find(uniqueId); if (info == null) { Console.WriteLine("Message not found, probably deleted?"); } else { // read the sequence number int sequenceNumber = info.SequenceNumber; // and use it to download the message client.GetMessage(sequenceNumber, localPath); } client.Disconnect();
Dim localPath As String = "" 'some valid unique ID we already retrieved in past Dim uniqueId As String = "abcd13954986" 'create client, connect and log in Dim client As New Pop3 client.Connect("pop3.example.org") client.Login("username", "password") 'get message list Dim messages As Pop3MessageCollection = client.GetMessageList() Dim info As Pop3MessageInfo = messages.Find(uniqueId) If info Is Nothing Then Console.WriteLine("Message not found, probably deleted?") Else 'read the sequence number Dim sequenceNumber As Integer = info.SequenceNumber 'and use it to download the message client.GetMessage(sequenceNumber, localPath) End If client.Disconnect()
Retrieving the message list
To get a list of messages in the mailbox, call the GetMessageList
method.
It accepts an optional parameter that specifies what information to retrieve from
the server:
Parameter value | Description |
---|---|
Pop3ListFields.SequenceNumber
|
Message sequence number for current session. |
Pop3ListFields.UniqueID
|
Message unique ID that is permanent and does not change between sessions. |
Pop3ListFields.Length
|
Message data size in bytes. |
Pop3ListFields.Fast
|
Combination of SequenceNumber , UniqueId and Length .
This is the default for GetMessageList method if no fields argument is specified.
|
Pop3ListFields.FullHeaders
|
Same as Fast , but also downloads the message headers of each message
as Date, From, To, Subject or Message ID fields. This variant is the most verbose,
but also the slowest. See the next section for more discussion about this.
|
These fields are bit flags, which means that combinations of SequenceNumber|Length
and UniqueId|Length
are also possible - use
bitwise OR
operator for this (|
in C#, Or
in VB.NET).
The following code shows how to download a message list and show a unique ID and From/Subject headers of each message:
// create client, connect and log in Pop3 client = new Pop3(); client.Connect("pop3.example.org"); client.Login("username", "password"); // get message list - full headers Pop3MessageCollection messages = client.GetMessageList(Pop3ListFields.FullHeaders); // display info about each message Console.WriteLine("UID | From | To | Subject"); foreach (Pop3MessageInfo message in messages) { Console.WriteLine ( "{0} | {1} | {2} | {3}", message.UniqueId, message.From, message.To, message.Subject ); } client.Disconnect();
'create client, connect and log in Dim client As New Pop3 client.Connect("pop3.example.org") client.Login("username", "password") 'get message list - full headers Dim messages As New Pop3MessageCollection messages = client.GetMessageList(Pop3ListFields.FullHeaders) 'display info about each message Console.WriteLine("UID | From | To | Subject") Dim message As Pop3MessageInfo For Each message In messages Console.WriteLine( _ "{0} | {1} | {2} | {3}", _ message.UniqueId, _ message.From, _ message.To, _ message.Subject) Next client.Disconnect()
Downloading message headers
The simplest method for downloading all message headers is to call GetMessageList
with
parameter Pop3ListFields.FullHeaders
, as described in the
Retrieving the message list
tutorial. It retrieves headers for all messages in the mailbox.
However, as mentioned earlier, this might take a very long time if there are too many messages
in the mailbox or the connection bandwidth is limited. If this is the case, it is
advisable to only ask for the message list with the IDs and length (Pop3ListFields.Fast
)
and retrieve message headers of each message separately using the GetMessageInfo
method - and this can even be done later or only when needed.
// create client, connect and log in Pop3 client = new Pop3(); client.Connect("pop3.example.org"); client.Login("username", "password"); int sequenceNumber = 1; // the first message Pop3MessageInfo info = client.GetMessageInfo ( sequenceNumber, Pop3ListFields.FullHeaders ); Console.Write("Date: " + info.Date); Console.Write("From: " + info.From); Console.Write("Subject: " + info.Subject); client.Disconnect();
'create client, connect and log in Dim client As New Pop3 client.Connect("pop3.example.org") client.Login("username", "password") Dim sequenceNumber As Integer = 1 'the first message Dim info As Pop3MessageInfo = client.GetMessageInfo( _ sequenceNumber, _ Pop3ListFields.FullHeaders) Console.Write("Date: " & info.Date.ToString()) Console.Write("From: " & info.From.ToString()) Console.Write("Subject: " & info.Subject) client.Disconnect()
Downloading messages
Finally, let's start downloading some messages! It is very simple - just call the
GetMailMessage
method and you retrieve an instance of the MailMessage
class that contains the message corresponding to the supplied sequence number. You
can read message headers, body and attachments from it, modify it, save it to disk
or send it again using our Smtp
class. For more info about this, check
out our MailMessage class tutorial.
Alternatively, if all you need is to download the message data and save it to disk
or write it into a stream, and you don't need to access the message content in any
way at the moment, just call the GetMessage
method instead. This won't
return an instance of MailMessage
and just writes the message data into
the supplied local path or stream.
// create client, connect and log in Pop3 client = new Pop3(); client.Connect("pop3.example.org"); client.Login("username", "password"); // get message list Pop3MessageCollection list = client.GetMessageList(); if (list.Count == 0) { Console.WriteLine("There are no messages in the mailbox."); } else { // download the first message MailMessage message = client.GetMailMessage(list[0].SequenceNumber); //... } client.Disconnect();
'create client, connect and log in Dim client As New Pop3 client.Connect("pop3.example.org") client.Login("username", "password") 'get message list Dim list As Pop3MessageCollection = client.GetMessageList() If list.Count = 0 Then Console.WriteLine("There are no messages in the mailbox.") Else 'download the first message Dim message As MailMessage = client.GetMailMessage(list(0).SequenceNumber) '... End If client.Disconnect()
Deleting and undeleting messages
Deleting messages in POP3 is quite straightforward, but might seem a bit awkward at first.
To delete a message, call the Delete
method with message sequence number as an argument.
The Delete
method marks a message as deleted. These won't appear in subsequent
message lists, but will actually only be removed from the mailbox after a call to
Disconnect
method. You can "undelete" messages that were not yet removed
using one of the following methods:
-
Calling
Undelete
method. This recovers messages marked as deleted. It will appear in message lists again and won't be removed when the session ends. -
Calling
Disconnect(true)
. This will undelete all deleted messages and disconnect from the server. No deleted messages will be removed, and the next time you connect to this mailbox, they will be there again. CallingDisconnect()
without parameter will commit all changes and remove all messages marked as deleted.
// create client, connect and log in Pop3 client = new Pop3(); client.Connect("pop3.example.org"); client.Login("username", "password"); int sequenceNumber = 1; // delete the first message client.Delete(sequenceNumber); // undo the delete operation client.Undelete(); // and delete it again client.Delete(sequenceNumber); // commit changes and disconnect client.Disconnect();
'create client, connect and log in Dim client As New Pop3 client.Connect("pop3.example.org") client.Login("username", "password") Dim sequenceNumber As Integer = 1 'delete the first message client.Delete(sequenceNumber) 'undo the delete operation client.Undelete() 'and delete it again client.Delete(sequenceNumber) 'commit changes and disconnect client.Disconnect()
Using events and logging communication
In case something goes wrong, it is very useful to have a log of commands sent to
the server and responses received from it for diagnostics purposes. To make this
possible, the Pop3
class declares the following events:
Event name | Description |
---|---|
CommandSent | Occurs when a command (for example CAPA or RETR) is sent to the server. |
ResponseRead | Occurs when response is received from the server. |
StateChanged | Occurs when the session state changes, such as from Disconnected to Ready, from Ready to Sending or from Sending to Reading. |
TransferProgress | Occurs when a block of message data is received from the server. |
The CommandSent or ResponseRead events are particularly useful for the purpose of generating a communication log and the TransferProgress event can be used by a GUI application to display amount of transfered data or a progress bar.
Pop3 client = new Pop3(); client.CommandSent += client_CommandSent; client.ResponseRead += client_ResponseRead; client.Connect("pop3.example.org");
Dim client As New Pop3 AddHandler client.CommandSent, AddressOf client_CommandSent AddHandler client.ResponseRead, AddressOf client_ResponseRead client.Connect("pop3.example.org")
Back to tutorial list...