IMAP (Internet Message Access Protocol) is an email messaging protocol which allows transferring of e-mail messages from a server. The protocol is based on commands which are sent from a client such as Mozilla Thunderbird or Microsoft Outlook. These commands allow you to login to a mailbox, get the total message count and the unread message count, view your messages, as well as create, delete, and rename mailboxes.
There are many IMAP controls available for various programming languages, and many articles explaining how to use these controls, but what if you would like to understand how the protocol is used to help you develop your own IMAP control? You may want to develop a small application that sits on your desktop informing you of new emails, or just displaying how many unread email messages you have. If you’re a very adventurous developer, you can try to develop your own email client.
In this article, I will explain how to connect to a mailbox to retrieve emails. This article is intended to be a brief introduction to some of the main IMAP commands. I will not discuss any error handling to make the code more understandable. You can add the error handling yourself.
Connecting to the mailbox
IAMP operates on port 143. In order to connect to the mailbox, we need to connect to this port number using a hostname.
Listing 1.1 below shows all the namespaces we need to include in our project.
Now that we have included the required namespaces, let’s start coding by declaring all the classes we need. Listing 1.2 below shows all the classes we need to declare.
private TcpClient _imapClient;
private NetworkStream _imapNs;
private StreamWriter _imapSw;
private StreamReader _imapSr;
We are going to use the
TcpClient class to connect to the mailbox server on port 143. Examine the
InitializeConnection() method in listing 1.3 below.
private void InitializeConnection(string hostname, int port)
_imapClient = new TcpClient(hostname, port);
_imapNs = _imapClient.GetStream();
_imapSw = new StreamWriter(_imapNs);
_imapSr = new StreamReader(_imapNs);
Console.WriteLine("*** Connected ***");
catch (SocketException ex)
InitializeConnection() method takes two arguments, the mailbox hostname and the port number. A
TcpClient is instantiated, and the
NetworkStream class is used to read and write to the stream. A
SocketExeption will be raised if the
_imapClient object is unable to connect to the mailbox server.
After successfully connecting to the mailbox server, the server will respond with a message. This is usually an “OK” message indicating that you have connected to the server. The code in Listing 1.4 below shows a very simple method to receive data from the mailbox server.
private string Response()
byte data = new byte[_imapClient.ReceiveBufferSize];
int ret = _imapNs.Read(data, 0, data.Length);
Every time we send a command to the mailbox server, we will use the above
Response() method to get the response data from the mailbox server. After getting a response from the server, we need to login using our login credentials.
The first command we will send to the mailbox server is the login command. Listing 1.5 below is the
AuthenticateUser() method, which takes two arguments, the username and the password.
public void AuthenticateUser(string username, string password)
_imapSw.WriteLine("$ LOGIN " + username + " " + password);
AuthenticateUser() method sends a “LOGIN” command to the mailbox server. The structure of this command is shown below.
PREFIX LOGIN USERNAME PASSWORD
Each command is followed by a prefix. In the
AuthenticateUser() method, the prefix used is the $ symbol. You can use a different prefix of your own, but some characters such as * will not work. Take notice of the
Response() method which is being called from the
AuthenticateUser() method. As I mentioned earlier, every time we send a command to the mailbox server, we need to get the response from the server. You can print the response to the console, but I decided not to do this.
If the supplied username and password are successfully authenticated, the server will respond with a message such as "$ OK User Loged In". Notice the prefix at the beginning of the message. This prefix will be the prefix you are using.
If, however, your login credentials are not authenticated, the server will respond with a message such as "$ NO Login failed: authentication failure". Using the server's response message, you can do your own exception handling. You can read the first four characters from the response, and determine if the response was an OK or a NO, in which case you can inform the user.
After successful authentication, we can perform a number of tasks, such as get the total number of messages. The
MailCount() method in listing 1.6 sends a command to examine the INBOX folder and get the total message count from the server.
public int MailCount()
_imapSw.WriteLine("$ STATUS INBOX (messages)");
string res = Response();
Match m = Regex.Match(res, "[0-9]*[0-9]");
The STATUS command takes two arguments. The first is the folder, and the second is what is known as a flag. The flag (
messages) indicates that you want to get the total number of messages in the inbox. If the command was executed successfully, the server will respond with a message similar to the following:
* STATUS INBOX (MESSAGES 3)
Notice that the server has responded with the total message count in the INBOX folder; in the above response, the total message count is 3. We can also find out how many new messages there are in the inbox. The
MailUnreadCount() in listing 1.7 below sends a STATUS command, but it sends an (unseen) flag. This flag tells the mailbox server to return the total count of unread messages.
public int MailUnreadCount()
_imapSw.WriteLine("$ STATUS INBOX (unseen)");
string res = Response();
Match m = Regex.Match(res, "[0-9]*[0-9]");
It is time to get some messages from the mailbox server. Before we begin to fetch any messages, we must first select the folder to retrieve the messages from. The
SelectInbox() method selects the INBOX folder. After selecting the INBOX folder, we can begin to get messages. Listing 1.8 below sends the SELECT command to the server to select the INBOX folder.
public void SelectInbox()
_imapSw.WriteLine("$ SELECT INBOX");
Finally, we can now send a command to get a single message from the mailbox sever. The command used to get a message is the FETCH command. This command takes two arguments: the first is the message number to retrieve, and the second is a combination of message flags. The
GetMessageHeaders () method in Listing 1.9 below takes a single argument of type
public object GetMessageHeaders(int index)
_imapSw.WriteLine("$ FETCH " + index +
" (body[header.fields (from subject date)])");
The above method
GetMessageHeaders() sends a FETCH command to the mailbox server, and only gets the from, subject, and date fields from the header of a selected message. This is useful if you want to display messages in a list control to show all the messages, but not the message body.
To get the body of the email, you need to send the FETCH command to the server, but you use the
body[text] flag. Listing 2.0 below shows the command to get the message body.
public object GetMessage(int index)
_imapSw.WriteLine("$ FETCH " + index + " body[text]");
Finally, after we have finished with the mailbox server, we need to logout. This is as easy as sending a LOGOUT command to the server. Listing 2.1 below shows the
Disconnect() method which sends a logout command to the mailbox server.
GetMessage() methods will return a response which is not formatted. You will need to format the response from the server, and add your own error handling by handling exceptions. To keep the code simple, I have not added any exception handling.