Microsoft & .NETVisual BasicMaking a POP3 Client

Making a POP3 Client

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

In today’s computing world, most people rely on such programs as Microsoft Outlook or Eudora to handle all their email wants. But what happens when you need to seriously customize the way it works? OK, so Outlook now supports VBA scripting, but that still leaves you having to have Outlook installed and handle its object model. In this article, I will teach you the basics of communicating with a POP3 internet server, and reading mail.

Well, lets start with the basics first. POP3 stands for Post Office
Protocol version 3. It is (along with IMAP) the standard protocol for
receiving email across a network. You only need several things to
connect. These include a valid username and password, and the address of
the POP server. For those of you using a dial up connection, this
address will probably look something like this:

pop.ispname.com

Where ispname is the name of your Internet Service Provider. That is
it as far as the normal email client goes, but when you have to do the
business yourself, you need to know a little more about how everything
works.

To start with, you need to connect to the correct port. Usually, the
standard port for POP communications is port 110. If you know that you
Local Area Network uses a different port, then you will need to make
sure that you set that when connecting.

For this article, I used the Winsock control to operate with. I will
now give a few details about how the Winsock control operates.

The Winsock control does not provide us with many properties, but the
ones we have, along with the methods and events make it a very powerful
control. If you have read my previous article about the Winsock control
(see Communicating over a network) then you will know how easy it is to
connect two PCs together and send some data. In that example, we had to
define a standard protocol for sending messages. First we sent the type
of content, then the size and then the content. To communicate with a
POP server, you need to understand the commands used.

A good way to learn about the commands is by downloading the trial
version of MDaemon (http://www.mdaemon.com/)
This is a very good mail server that allows you to see all the messages
that are sent and received when it communicates with another server.

Anyway, let me explain how things work.

When you send some data, you have a keyword first, such as USER, then
the value, and then a vbCrlf character. Below I have listed some of the
commands used in the sample project:

  • USER – Sends the username
  • PASS – Sends the password
  • QUIT – Ends the current session
  • DELE – Deletes a mail message from the server
  • RSET – Undos any changes made within the current session
  • STAT – Returns the number of messages on the server
  • RETR – Retrieves the content of a message

I won’t go through what each one does because the descriptions are
pretty self explanatory. Anyway, after sending a message, you need to
listen for a reply. If everything is working, then you will receive a
+OK message back from the server. If there is a problem, then the server
will return a -ER message. Here is some code that sends a user id:

Winsock1.SendData "USER Sam" & vbCrlf

To get the response from the server, we need to look in the
Winsock1_DataArrival event. This event does not actually provide us with
any data, it just notifies us that data is arriving and how big it is.
We need to use the Winsock1.GetData method to retrieve something:

Private Sub WInsock1_DataArrival(ByVal bytesTotal As Long)
Dim strData As String

Winsock1.GetData strData, vbString
WholeThing = WholeThing & strData
ResponseState = Left$(WholeThing, 3)

End Sub

The GetData method accepts two parameters. The first is a variable
where the data retrieved can be placed in and the second is the format
in which to receive the data. In the example above, we fill the
ResponseState variable with what will either be a +OK command or a -ER
command. The best thing to do is to make the ResponseState variable a
private/public member of the module so that the program can detect
whether it is ok to proceed.

The Winsock control also provides a Winsock1_Error event. This event
gives us plenty of information about the error, helping us to tell the
user what has happened. Here is a sample Winsock1_Error event procedure:

Private Sub Winsock1_Error(ByVal Number As Integer, _
  Description As String, ByVal Scode As Long, _
  ByVal Source As String, ByVal HelpFile As String, _
  ByVal HelpContext As Long, CancelDisplay As Boolean)

  Msgbox "Error number: " & Number & vbCrlf & _
    "Error Description: " & Description

End Sub

The thing that I like very much about doing your own POP comms is
that you can choose to leave the messages on the server. This way you
can be on the road, download your email and read it, then reply to the
important ones and delete them from the server so you know they are
gone, and then disconnect leaving the rest of your mail intact, allowing
you to pick it up back at the office/home. You could extend the sample
program to store the email on your hard drive, so that you can look at
it later.

If you are thinking about deploying email access on the web, then I
wouldn’t try and just put a VB control on there because it runs very
slowly and requires you to download the runtimes and any additional
controls onto your machine if they are not already there. I would
suggest writing a Perl or Java program or possibly wrapping it into a VB
DLL and using ASP to view it. To get a good look at a service that
deploys web email, and allows you to download email from other servers,
check out BT’s Talk21 service: http://www.talk21.com/

So, lets make a connection! First, I will put out the code and after
you have had a look through it, I will explain what’s going on:

Private Function ConnectToPOP(strServer As String, _
  strUser As String, strPwd As String)As Boolean

Dim strOut As String

ConnectToPOP = False

Winsock1.Connect strServer, 110 
   ' Change the port as necessary
WaitFor 1, strOut

If strOut = "+OK" Then
  Winsock1.SendData "USER " & strUser & vbCrlf
Else
  ConnectToPOP = False
  Exit Function
End If

WaitFor 1, strOut

If strOut = "+OK" Then
  Winsock1.SendData "PASS " & strPwd & vbCrlf
Else
  ConnectToPOP = False
  Exit Function
End If

WaitFor 1, strOut

If strOut = "+OK" Then
  ConnectToPOP = True
Else
  ConnectToPOP = False
End If

End Function

As you can see, the function takes a bit of getting used to.
Remember, after each time we send some data, we have to wait for a
response. I have wrapped the waiting code into a procedure called
WaitFor (you can see this in the sample project). Firstly, we use the
Winsock1.Connect method and specifiy the server and the port to connect
on. We then wait for a response, and check that the response is +OK,
otherwise we bail out. If the response was +OK, then we send the
username using the USER command. Again, we wait for a response and if
everything is ok, we send the password. If after all this sending,
waiting and checking things are still ok, then we are now connected to
the server!

The next thing we want to do is to download a list of the messages on
the server. To do this we use the STAT command. In the sample code you
will notice that I have used a User Defined Type structure and an array
to store each message in. You may come up with another way that is
better or more suited to your needs, but for the moment, I will just
present the UDT:

Type tMailItem
  From As String
  Subject As String
  DateSent As String
  Bytes As Long
  Body As String
  Loaded As Boolean
  Deleted As Boolean
End Type

The names tell you quite basically what each one does. I would just
like to point out that the last two properties, Loaded and Deleted play
an important part in the sample project. The Loaded flag tells us if the
message is currently loaded in the viewing window. The Deleted flag
tells us if the message is to be deleted from the server when we
disconnect. Any incorrect handling of the Deleted flag could cause
serious problems in your application.

I hope that this article has given you enough understanding to be
able to download the sample project (a fully functional POP client) and
look through the code and know what’s going on.


Download the code

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories