Introduction
In this tutorial, we will learn about Post Office Protocol (POP3). It is a protocol (a set of commands) used by an email client to connect to and retrieve email(s) from the mailbox on the remote server. We will develop the code that connects to the POP3 server and sends commands to retrieve the list of emails on the server, and then later, using an ASP.NET page, displays the list to the user. To demonstrate the code, we will be connecting to Gmail's POP3 server using SSL (Secure Sockets Layer).
To connect to your own POP3 mail server, you can either use the secure connection (SSL) if your mail server supports it or connect in unsecure mode. The code is simple to understand and by looking at it you will learn a lot about how network programming is done in the .NET environment.
Note: In this tutorial, we will limit ourselves to retrieving and displaying a list of emails from user's mailbox which the user can browse through using 'Previous Page' and 'Next Page' links. In the next tutorial (
Displaying Emails from Mailbox on Gmail using POP3 and ASP.NET), we will learn how to retrieve and view an individual email.
Following screen shot shows an ASP.NET page listing emails in my Gmail mailbox:
If you are looking for a production ready, stable, easy to use ASP.NET Newsletter application, then look no further:
Faisal Khan (the author of this tutorial) has created a great Newsletter Application for you to download and start using today. It is easy to install, lets your users subscribe using a subscription form, provides a simple administration interface to create and send newsletters, handles the task of sending newsletters in the background using thread queues on the server, and lets users unsubscribe if they wish so.
Basic POP3 Commands
Following is a list of commonly used POP3 commands:
USER - Takes one argument i.e., the email address of the user trying to connect to his/her mailbox. Example usage:
USER youremail@xyz.com
PASS - Takes one argument i.e., the password of the user. Example usage:
PASS yourpassword
STAT - Returns the number of emails in the mailbox and the number of bytes all the emails are taking on the server. Example usage:
STAT
TOP - Takes two arguments i.e., the sort number of the email on the server and the number of lines of text to retrieve from the body of the email. Example usage:
TOP 1 10
RETR - Takes one argument i.e., the sort number of the email on the server and returns all the headers and lines from the body of the email. Example usage:
RETR 1
DELE - Takes one argument i.e., the sort number of the email on the server and deletes it. Example usage:
DELE 1
RSET - Resets any DELE commands given above. The emails marked to be deleted by DELE command are unmarked. Example usage:
RSET
QUIT - Closes the user session with the server. Example usage:
QUIT
Note: In the code that we will develop, we will not close the session with the remote server using QUIT command. Because if we have issued RETR command to retrieve any emails from the POP3 server, issuing QUIT commands gives the wrong impression to the server that those emails have been downloaded safely on our system so the server can remove them from its list. Since we do not want to inadvertently remove or delete any emails from the POP3 server, we will not issue QUIT command and simply close the connection.
Developing the Code
In this tutorial, we will develop C# classes that encapsulate all the code that is necessary to connect to and retrieve emails from Gmail's mailbox. We will place these classes in "Pop3.cs" C# source file. These classes will provide an easy to use interface to access the mailbox. An ASP.NET page with the name of "Pop3Client.aspx" will use these classes to list emails in the mailbox.
Files that we will develop in this tutorial:
Pop3.cs
Pop3Client.aspx
i. Pop3.cs
All right guys, open Notepad and copy following code in it. Then save this new document as Pop3.cs in the /App_Code folder of your ASP.NET web application:
/* Author: Faisal Khan */
/* © Stardeveloper.com */
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml;
namespace Stardeveloper.Pop3
{
public class Pop3Client : IDisposable
{
public string Host { get; protected set; }
public int Port { get; protected set; }
public string Email { get; protected set; }
public string Password { get; protected set; }
public bool IsSecure { get; protected set; }
public TcpClient Client { get; protected set; }
public Stream ClientStream { get; protected set; }
public StreamWriter Writer { get; protected set; }
public StreamReader Reader { get; protected set; }
private bool disposed = false;
public Pop3Client(string host, int port, string email,
string password)
: this(host, port, email, password, false)
{
}
public Pop3Client(string host, int port, string email,
string password, bool secure)
{
Host = host;
Port = port;
Email = email;
Password = password;
IsSecure = secure;
}
public void Connect()
{
if (Client == null)
Client = new TcpClient();
if (!Client.Connected)
Client.Connect(Host, Port);
if (IsSecure)
{
SslStream secureStream =
new SslStream(Client.GetStream());
secureStream.AuthenticateAsClient(Host);
ClientStream = secureStream;
secureStream = null;
}
else
ClientStream = Client.GetStream();
Writer = new StreamWriter(ClientStream);
Reader = new StreamReader(ClientStream);
ReadLine();
Login();
}
public int GetEmailCount()
{
int count = 0;
string response = SendCommand("STAT");
if (IsResponseOk(response))
{
string[] arr = response.Substring(4).Split(' ');
count = Convert.ToInt32(arr[0]);
}
else
count = -1;
return count;
}
public Email FetchEmail(int emailId)
{
if (IsResponseOk(SendCommand("TOP " + emailId + " 0")))
return new Email(ReadLines());
else
return null;
}
public List<Email> FetchEmailList(int start, int count)
{
List<Email> emails = new List<Email>(count);
for (int i = start; i < (start + count); i++)
{
Email email = FetchEmail(i);
if (email != null)
emails.Add(email);
}
return emails;
}
public List<MessagePart> FetchMessageParts(int emailId)
{
if (IsResponseOk(SendCommand("RETR " + emailId)))
return Util.ParseMessageParts(ReadLines());
return null;
}
The code continues on the next page.