IMAP4, charting the future of Email


When we completed our POP3 and SMTP tutorials we thought we were through with mail protocols once and for all. Alas! what folly! Protocols, like well made Jell-O, stand still for no man (or woman in these liberated times). No sooner had we turned our eyes to other matter that up pops another mail protocol. It goes by the evocative name of IMAP4 which stands for Internet Message Access Protocol, revision 4. Well, we've always prided ourselves for covering everything under a single topic, no matter what that topic may be and we couldn't just let a new protocol go by without writing something about it.

So we sat down and read the various RFC's on the subject and after a while decided to write a small tutorial about it. One thing that really put us off the protocol was the stilted syntax. I haven't read such atrocious English since the last time I decided to help my four year old cousin with his home-work! But who cares about the sensibilities of computer programmer anyway?

At first glance the protocol seems quite advanced (except for the English!) and that impression is further strengthened the more you read about it. Our first impression of this protocol was quite favorable and after using an IMAP4 client for some days, I fell in love with it. I just adore the fact that I nolonger have to download all my mail to read just one important message; a major advantage of this protocol over POP3. If you want to read more about the advantages of IMAP4 over POP3 and vice-versa, skip over to the IMAP4 vs POP3 discussion at the end.

Before we start programming, a bit about the protocol...

What exactly is IMAP4?

IMAP4 is the fourth revision of the Internet Message Access Protocol or as it was once known, the Interactive Mail Access Protocol. IMAP4 is a protocol which deals exclusively with the handling of email on the client side. It has absolutely nothing to do with the actual sending of email; that's SMTP's (Simple Mail Transfer Protocol) job.

IMAP4 is after POP3's (The Post Office Protocol, version 3) job and the authors realized that no one would want to switch from POP3, which is an extremely popular and well supported protocol, to IMAP4, which has still to prove itself out in the shark infested waters of the Internet, unless it offered some significant advantages over the latter. They also knew that they could not radically alter the model of the protocol without alienating every Internet programmer on the planet. So IMAP4 feels a lot like POP3 and offers a superset of the features that the latter supports, which means that IMAP4 supports more complex interaction between server and client and allows for more efficient mail handling.

The IMAP4 partadigm differs from POP3 in one crucial area. POP3 believes in downloading all the mail at once from the server and then allowing the user to read his correspondence off-line. IMAP4 on the other hand believes that the mail-box and the messages it contains should reside on the server. The user can download the mail, read it and delete it but the message inbox is always maintained by the server. Even if all the mail is downloaded to the client machine, the server still maintains a copy, unless specifically ordered to erase a message.

IMAP4's main advantage over it's rival is that it takes into account the fact that a majority of users will be accessing their mail over a slow-speed dial-up connection. It allows the client machine to just bring in the message headers and envelope information like the subject, the senders address etc. and leave the message body on the server. Only if the user clicks on a message will it be downloaded to the client machine. This is a much better way of handling mail than just picking it up and dumping it on your hard disk.

Another significant advantage is that IMAP4 can break up and download selective parts of a multi-part (an email with attachments) mail. So if you get a email with 2KB of text and 10MB of attachment files, you can, if you want, simple download and read the text portion and leave the attachment on the server! Quite a change from POP3 which would have mindlessly download all of the message without informing you that less that 1% of the package was human readable text.

IMAP4 also allows you to maintain multiple mail-boxes on multiple servers. In this way you can have two or more mail-boxes on the same server, under the same account. So, for example, you can now have three mail-boxes; INBOX, which is the default, BUSINESS, for all your business mail and FAMILY to hold all those messages from your mom. You can also nest your mail-boxes in a folder hierarchy, so BUSINESS can be further subdivided into CUSTOMERS and the COMPANY. There's support for both standard and user-definable message flags and server based searching is also supported. You can even have a single mail-box which can be accessed by many users at the same time!

But enough talk now!! The main reason you're here is to learn how to write a simple IMAP4 client and that's exactly what we're going to show you how to do, so onwards!

The Setup...

But first! is your computer ready for this task? You'll need to have some Internet IMAP4 compatible mail server running on your machine, or you'll have to connect to one. What we did was install WindowsNT Server on one machine and then run Netscapes' Mail server for WindowsNT on it. The server proved to be the very devil to setup! You must have Netscape 3.0 installed on your machine before you start and No!, Netscape 4.0 beta will not do! Infact, if you try it with 4.0, the administrative server will refuse to start! Also be sure not to delete the directory in which the server unzipped itself, because if you ever need to uninstall it, then the installation log files in creates are vital. I learn't this the hard way!

We used Microsoft's Visual C++ 4.0 for all our compiling needs.

Before you can understand any of these programs, you have to understand some amount of WinSock programming (check out our tutorial). It's best of you read RFC's 1730 - 1733. Of these four RFC's on IMAP4, RFC 1730 is the largest and the most important. Infact, this whole tutorial has been cobbled together after reading that one RFC!! (Our secrets out!!) If you intend to make some serious IMAP4 clients then you'd better know these RFC's backwards or more importantly, forwards.

This is the best site I've ever found for RFC's. Check it out once, and you'll be hooked.

The programs

Create a new project workspace under Visual C++ 4.0 and insert two files into it; client.cpp and wsock32.lib which is the .lib we need to write WinSock code. Start typing these programs in one by one and see what they do...

client1.cpp

void flush(char *fl, int len);

#include <stdio.h>
#include <windows.h>

void abc(char *s)
{
FILE *fpi;
fpi=fopen("z","a+");
fprintf(fpi,"%s\n",s);
fclose(fpi);
}

WSADATA ws;
SOCKET s;
struct sockaddr_in Sock;

int main()
{
char msg[100];
char get[5000];

WSAStartup(0x0101,&ws);
printf("WSAStartup\n");

s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
printf("socket\n");

Sock.sin_family=AF_INET;
Sock.sin_port=htons(143);
Sock.sin_addr.s_addr=inet_addr("127.0.0.1");
printf("Sock.sin.. done\n");

connect(s,(struct sockaddr *)&Sock,sizeof(Sock));
printf("connect\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"1 capability\r\n");
printf("strcpy capability\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

closesocket(s);
WSACleanup();

printf("\n\nDone\n");

return 0;
}

void flush(char *fl, int len)
{
int i;
for(i=0;i<=len;i++)
{
	fl[i]=0;	
}
}

The very first line of the program is a function prototype for flush(), a cute little procedure that clears up the recv() buffer after it's been used. I used it because when I ran the programs on my WindowsNT server, part of the output seen to be swallowed up after the first few recv()'s. So I wrote flush() to clear up the buffer, just in case that was the cause of the problem.

The next two lines include the headers we need, the chief one of which is the windows.h header file. This header in turn calls the winsock.h header file.

After that we have our custom function abc() which takes the address of a string as its parameter and then writes that to a file on disk.

Right after abc(), we initialize some global variables and structures. Ws looks like WSADATA whish is a structure tag in windows.h. After that we have another #define, SOCKET which is an unsigned int. We then declare Sock as a structure which looks like sockaddr_in.

The first significant function we meet in main() is WSAStartup(). WSAStartup() is essential for WinSock programming and this program couldn't operate without it. It helps us tell the WinSock .dll what version of the WinSock we require. In our case we're asking for WinSock version 1.01 which is what 0x0101 means. WSAStartup() also fills up the structure ws with what the books cryptically call "important information ". This information turns out to be not so important after all since we never end up using any of it inour programs!

After WSAStartup(), we have another important function, socket(). The socket function creates a socket of the type specified and returns a handle to that socket. Here we're telling the function to create a socket of protocol family Internet (PF_INET), which means we'll be using this socket on the Internet. The next parameter tells the function that the protocol used over the lines will be a stream oriented protocol like TCP (SOCK_STREAM) and not a datagram oriented one like UDP (SOCK_DGRAM). The final parameter informs the function that the protocol to be used is TCP/IP. The handle to the socket is now stored in s which must be a positive number.

After we've called socket(), we initialize some of the members of the structure Sock. We initialize Sock.sin_family to AF_INET which means that the socket will be used over the Internet. Sock.sin_port is where we enter the port we wish to connect to, which is 143. Htons() converts that number into the Network Byte Order. In Sock.sin_addr.s_addr we place the IP address we wish to connect to. I was working on the same machine as the server, so I used the LoopBack IP address of 127.0.0.1. The function inet_addr() convert the number from the Dotted Decimal Notation to a normal long number.

The next function is connect(), which as the name suggests, connects us to the server we've specified. We have to supply connect with the socket handle s, the address of the structure Sock (cast to struct sockaddr *) and it's size.

When we connect to an IMAP4 server, it sends us a message of greeting. We have to receive this greeting and that's why we start off with a recv() statement. The first time I wrote these programs, I forgot all about that and it took me a while to figure things out. If you don't put a recv() here, you won't be fully syncronised with the server and that can lead to problems. If you're adventurous, try the programs without this recv() and see what happens!

The parameters we pass to recv() are the socket handle s, the address of the buffer get, it's size and a 0 (The flags field).

The greeting the Netscape mail server sends us is :-

* OK Netscape IMAP4 Service 1.0 on zaidi at Thu, 4 Apr 1996 15:52:34 -0800 (PST)

Right after this recv and all others after it, we place a flush to clear out the buffers.

The first command we'll be sending the server will be a capability command. This command tells the server to return a string in which is listed all it's capabilities, for example, the number and kinds of authentication protocols it supports. Each IMAP4 command must begin with a hex number. This is because the server is not bound to process your commands in the order it gets them. So the numbers help identify the order of the commands. A bit like the ID field in the PPP protocol. When the server replies, it will prefix the command ID number to the reply string. for example, 1 OK CAPABILITY completed. Additionally, each command must end with a carriage return and a line feed, i.e. \r\n.

To send the command, we copy it into an array msg and then call the function send().

Send shoots the command, or any other data for that matter over the lines to the computer at the other end. It's parameters are identical to those of recv(), which is called next.

Recv() receives the servers response. and then abc writes it to disk. As usual, flush is called to clear the buffer.

The response we got for this command was :-

* CAPABILITY IMAP4 STATUS SCAN AUTH-SKEY AUTH-LOGIN
1 OK CAPABILITY completed

We now wind up the program by calling closesocket() which accepts the socket handle as the parameter and frees all the memory occupied by our socket. WSACleanup() performs some house keeping functions. We then print out "Done" and exit.

client2.cpp

void flush(char *fl, int len);

#include <stdio.h>
#include <windows.h>

void abc(char *s)
{
FILE *fpi;
fpi=fopen("z","a+");
fprintf(fpi,"%s\n",s);
fclose(fpi);
}

WSADATA ws;
SOCKET s;
struct sockaddr_in Sock;

int main()
{
char msg[100];
char get[5000];

WSAStartup(0x0101,&ws);
printf("WSAStartup\n");

s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
printf("socket\n");

Sock.sin_family=AF_INET;
Sock.sin_port=htons(143);
Sock.sin_addr.s_addr=inet_addr("127.0.0.1");
printf("Sock.sin.. done\n");

connect(s,(struct sockaddr *)&Sock,sizeof(Sock));
printf("connect\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"1 capability\r\n");
printf("strcpy capability\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"2 login zaidi ARSALAN\r\n");
printf("strcpy login\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

closesocket(s);
WSACleanup();

printf("\n\nDone\n");

return 0;
}

void flush(char *fl, int len)
{
int i;
for(i=0;i<=len;i++)
{
	fl[i]=0;	
}
}

In this program, we send a login command with the username and the password (username = zaidi, password = ARSALAN). We have to login using a username and password before we can do anything much. Infact, before we're authenticated, we can use only three commands, capability, login and logout.

We're using a simple login here because I didn't have the heart to tackle one of the authentication protocols IMAP4 supports.

The response we got for this command was :-

2 OK LOGIN completed

client3.cpp

void flush(char *fl, int len);

#include <stdio.h>
#include <windows.h>

void abc(char *s)
{
FILE *fpi;
fpi=fopen("z","a+");
fprintf(fpi,"%s\n",s);
fclose(fpi);
}

WSADATA ws;
SOCKET s;
struct sockaddr_in Sock;

int main()
{
char msg[100];
char get[5000];

WSAStartup(0x0101,&ws);
printf("WSAStartup\n");

s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
printf("socket\n");

Sock.sin_family=AF_INET;
Sock.sin_port=htons(143);
Sock.sin_addr.s_addr=inet_addr("127.0.0.1");
printf("Sock.sin.. done\n");

connect(s,(struct sockaddr *)&Sock,sizeof(Sock));
printf("connect\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"1 capability\r\n");
printf("strcpy capability\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"2 login zaidi ARSALAN\r\n");
printf("strcpy login\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"3 select inbox\r\n");
printf("strcpy select\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

closesocket(s);
WSACleanup();

printf("\n\nDone\n");

return 0;
}

void flush(char *fl, int len)
{
int i;
for(i=0;i<=len;i++)
{
	fl[i]=0;	
}
}
In this program we select a mail-box using the select command. we have to select a mail-box before we can retreive mail or do anything else really useful. The Inbox mail-box is created by the server, by default. If the command is successful, we get a lot of data besides the "OK" response. This data is pretty useful. Notice that all server responses that are not command responses begin with a '*', infact, that's how we recognise them.

The response we received for the select command was:-


* 5 EXISTS
* OK [UIDVALIDITY 828575924] UID validity status
* FLAGS (\Answered \Flagged \Deleted \Draft \Seen)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Draft \Seen)] Permanent flags
* 1 RECENT
3 OK [READ-WRITE] SELECT completed

The meaning of all these statements isn't hard to fathom. Look up the RFC (1730) to read about them in detail.

client4.cpp

void flush(char *fl, int len);

#include <stdio.h>
#include <windows.h>

void abc(char *s)
{
FILE *fpi;
fpi=fopen("z","a+");
fprintf(fpi,"%s\n",s);
fclose(fpi);
}

WSADATA ws;
SOCKET s;
struct sockaddr_in Sock;

int main()
{
char msg[100];
char get[5000];

WSAStartup(0x0101,&ws);
printf("WSAStartup\n");

s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
printf("socket\n");

Sock.sin_family=AF_INET;
Sock.sin_port=htons(143);
Sock.sin_addr.s_addr=inet_addr("127.0.0.1");
printf("Sock.sin.. done\n");

connect(s,(struct sockaddr *)&Sock,sizeof(Sock));
printf("connect\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"1 capability\r\n");
printf("strcpy capability\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"2 login zaidi ARSALAN\r\n");
printf("strcpy login\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"3 select inbox\r\n");
printf("strcpy select\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"4 fetch 5 rfc822.text\r\n");
printf("strcpy fetch\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

closesocket(s);
WSACleanup();

printf("\n\nDone\n");

return 0;
}

void flush(char *fl, int len)
{
int i;
for(i=0;i<=len;i++)
{
	fl[i]=0;	
}
}
Finally, we're doing somthing worth our while. The fetch command is used to retreive a message. The parameters after the command can be many and confusing, but the one's here are pretty simple. We want to fetch the body of the message (as defined in RFC822) of message number 5.

The response the sever send us after the fetch was :-

* 5 FETCH (RFC822.TEXT {236}
Hi there,

This is a bogus mail from me to you!

I'm basically trying to fill up some space here and that's really why I'm placing all this bovine fecal matter here. For your reading pleasure!

Th-Th-That's All Folks!!!

Bye.
FLAGS (\Recent \Seen))
4 OK FETCH completed

That stupid stuff in the middle is the text of the message.

client5.cpp

void flush(char *fl, int len);

#include <stdio.h>
#include <windows.h>

void abc(char *s)
{
FILE *fpi;
fpi=fopen("z","a+");
fprintf(fpi,"%s\n",s);
fclose(fpi);
}

WSADATA ws;
SOCKET s;
struct sockaddr_in Sock;

int main()
{
char msg[100];
char get[5000];

WSAStartup(0x0101,&ws);
printf("WSAStartup\n");

s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
printf("socket\n");

Sock.sin_family=AF_INET;
Sock.sin_port=htons(143);
Sock.sin_addr.s_addr=inet_addr("127.0.0.1");
printf("Sock.sin.. done\n");

connect(s,(struct sockaddr *)&Sock,sizeof(Sock));
printf("connect\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"1 capability\r\n");
printf("strcpy capability\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"2 login zaidi ARSALAN\r\n");
printf("strcpy login\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"3 select inbox\r\n");
printf("strcpy select\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"4 fetch 5 rfc822.text\r\n");
printf("strcpy fetch\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

strcpy(msg,"5 logout\r\n");
printf("strcpy logout\n");

send(s,msg,strlen(msg),0);
printf("send\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);

closesocket(s);
WSACleanup();

printf("\n\nDone\n");

return 0;
}

void flush(char *fl, int len)
{
int i;
for(i=0;i<=len;i++)
{
	fl[i]=0;	
}
}

In this, the final program, we simply send the logout command to tell the server we're through with the connection. The server should respond with a BYE. The rest of the string can differ.

Netscape sends:-

* BYE zaidi IMAP4 server terminating connection
5 OK LOGOUT completed
Oh, and by the way, zaidi is the name of the host computer.

An IMAP4 Tester

void flush(char *fl, int len);

#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

void abc(char *s)
{
FILE *fpi;
fpi=fopen("z","a+");
fprintf(fpi,"%s\n",s);
fclose(fpi);
}

WSADATA ws;
SOCKET s;
struct sockaddr_in Sock;

int main()
{
char msg[100];
char get[5000];
int i; char Done=1;int length;
char input[100];

WSAStartup(0x0101,&ws);
printf("WSAStartup\n");
abc("WSAStartup\n");

s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
printf("socket\n");
abc("socket\n");

Sock.sin_family=AF_INET;
Sock.sin_port=htons(143);
Sock.sin_addr.s_addr=inet_addr("127.0.0.1");
printf("Sock.sin.. done\n");
abc("Sock.sin.. done\n");

connect(s,(struct sockaddr *)&Sock,sizeof(Sock));
printf("connect\n");
abc("connect\n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);
printf("\nNext command : ");

while (!Done)
{
gets(input);

length = strlen(input);
for (i=0; i<length; i++)
{
 input[i] = toupper(input[i]);
}

if (!strcmp(input,"EXIT"))
{
	Done=1;
}
else
{
strcpy(msg,input);
strcat(msg,"\r\n");

printf("%s\n",msg);
abc(msg);

send(s,msg,strlen(msg),0);
printf("\nsending	\n\n");
abc("sending \n");

recv(s,get,strlen(get),0);
abc(get);
printf("%s",get);
flush(get,5000);
printf("\nNext command : ");

Done=0;
}
}

closesocket(s);
WSACleanup();

printf("\n\nDone\n");
abc("\n\nDone\n");

return 0;
}

void flush(char *fl, int len)
{
int i;
for(i=0;i<=len;i++)
{
	fl[i]=0;	
}
}

I wrote this program to test out various IMAP4 commands. All you have to do is run the program, and type the command at the prompt. Remmember to begin your command with a hex number, or you'll get an error! An example would be 100a capability with a carriage return at the end. You can also alter the port number and use it to communicate with a HTTP of FTP server!

This program could do with some improvment. If you do make any changes (For the BETTER !!), then please email the source over to us at vmukhi@giasbm01.vsnl.net.in.

IMAP vs POP3

Okay, so why should anyone want to abandon a popular protocol like POP3 and step out on a limb by propagating IMAP4. Why should we, as both programmers and more importantly, as users, adopt IMAP4 as the message retrieval protocol of choice?

Well, if you're eady, here goes...

POP3 works on the store and forward model where mail is delivered to a common shared server (The SMTP server) which is called the 'drop point' which collects all the mesages. When the user logs on, the messages are immediatly forwarded to him and then usually deleted by the server. All mail rocessing is done on the client and server resouces are left reletavly free.

IMAP4 on the other hand accesses remote mail-boxes as if they were present on the local machine. The IMAP4 client can request any part of the message, such as the envelope or the headers and download the whole message only when needed. Server based searching is also supported. Messages are not deleted immediately, rather they are marked for deletion and only removed once the client logs off of sends the expunge command. A bit like Dbase where records are not really deleted until and unless PACKed off to the data Valhalla.

POP3 works best for people who use a single machine most of the time because it downloads all the mail onto the client as soon as it logs on. IMAP4 however, can server those people best who keep jumping all over the place and regularly use different machine. Because the messages are stored on the server, it doesn't really matter who or where the client is.

POP3's strength is in its availability and popularity. Almost all mail servers support POP3 as a retrieval protocol and most client programs can only use POP3. However, there is nothing in the protocol itself which is superior to IMAP4. Infact, since IMAP is simply a functional superset of POP3, it too can operate in the same way as POP3. If the user so desires, IMAP4 can behave like POP3 by connecting to a server and mindlessly downloading all that is present.

POP3 is also sometimes preferred because it is frugal when it comes to connection time or server resources. All POP3 does is connect to a server and download the mail, whereupon, the messages are promptly deleted. It doesn't support server searching or anything else for that matter. All processing is done locally. IMAP4 on the other hand is a bit more extravagant with connect time. Since it functions on the client-server model, you have to stay connected to do anything. Server based searching may help the user, but it slows down the server for all, especially if the machine is not a dedicated mail server. POP3's protocol is also a lot friendlier to write than IMAP4's. IMAP's server responses are extremely stilted and awkward to understand. Because it supports so many options and is quite open ended, it is also very verbose and slightly confusing. That however is not going to help POP3 much because the only people who'll suffer are the programmers and who cares for geeks anyway!!

IMAP4 also offers more order and organization on the server end of things. You can have multiple mail-boxes and nest them under one another in a folder hierarchy. It's startup time is also much shorter as it has only the headers to fetch. It's only when the user specifically selects a messages that the mail is downloaded. This leads to greater efficiency over low-speed links.

Another point in IMAP4's favor is that it offers better off-line mail handling than POP3, even though it is fundamentally a on-line client protocol. POP3 downloads all the mail onto one machine, which is probably running some version of Windows and is therefore quite capable of suddenly and inexplicably exploding in your face! Under POP3 you can explicitly tell the server not to delete the mail and thus face the nightmare of manually synchronizing the hundreds of messages stored in the two machines. IMAP4 on the other hand only 'marks' a message for deletion and doesn't deletes it until it is quite clear that it is unnecessary. It offers automatic resynchronization with the server if the need arises.

IMAP4 also supports advanced authentication techniques and provides for protocol extensibility. However, it's main advantage in my eyes over POP3 is it's ability to selectively download messages or part of messages from the server. This means that I no longer have to endure weary hours by the keyboard while a hundred spam messages from snake oil dealers, lawyers and Macintosh fanatics (some would argue they're all in the same league) tumble down the wires and snuggle down on my hard disk. I can now leave these and the messages from by mother-in-law safely where the belong, back on the server. Another boon that IMAP4 provides is the ability to download only selected portions of a message. This means that I nolonger have to wait for hours while an 1Kb email with 5Mb worth of audio files (5 minutes of ol' Bill saying "640 Kb should be enough for everybody" repeatedly) makes place for its self on my machine; when don't even have a sound card! With IMAP4, I can simply download the text portion, read it, snort, and expunge the mail from the server.

All in all, I find IMAP4 to be for advanced and flexible than POP3. It's smarter too and works just fine over a dial-up link. Make no mistake, this is the future. A reasonable conclusion is that the openly advantage POP3 holds over IMAP4 is that there is currently more POP3 compliant software available. This situation is changing rapidly and considering how long we've used POP3, none to soon.


The above tutorial is a joint effort of

Mr. Vijay Mukhi
Mr. Arsalan Zaidi


Back to the main page


Vijay Mukhi's Computer Institute
VMCI, B-13, Everest Building, Tardeo, Mumbai 400 034, India
Tel : 91-22-496 4335 /6/7/8/9     Fax : 91-22-307 28 59
e-mail : vmukhi@giasbm01.vsnl.net.in
http://www.vijaymukhi.com