Click here to Skip to main content
15,892,161 members
Articles / Programming Languages / Visual Basic
Article

Implement POP3 and SMTP in .NET

Rate me:
Please Sign up or sign in to vote.
4.56/5 (45 votes)
4 Jan 2006CPOL 632.4K   9.3K   133   204
Using socket to implement POP3 and SMTP protocol.

Introduction

This article shows how to use VB.NET to implement POP3 and SMTP protocol. There is a DLL file included in the source files, this DLL contains two classes to implement POP3 and SMTP and an extra class for e-mail's codec (base 64 only, not included in the source code because it is being tested now).

Any questions? Please contract me immediately at soldierq@msn.com.

Main functions in these Classes

The most basic functions are the same in POP3 class and the SMTP class.

Connect to Mail Server

VB
Private Function Connect() As Boolean
     Try
         sockPOP3.Connect(m_Remote)

         If sockPOP3.Connected = True Then
             sockPOP3.Receive(bufferReceive)
             Return True
         Else
             Return False
         End If
     Catch ex As Exception
         sockPOP3.Close()
         Throw New Exception("Failed to Connect " +
                     "Host:" & vbCrLf & ex.Message)
     End Try
 End Function

Send Commands to Server

VB
Private Function SendCommand(ByVal Command As String) As Byte()
    Try
        bufferSend = Encoding.ASCII.GetBytes(Command & vbCrLf)
        sockPOP3.Send(bufferSend)


        Array.Clear(bufferReceive, 0, bufferReceive.Length)
        sockPOP3.Receive(bufferReceive)

        Return bufferReceive
    Catch ex As Exception
        Throw New Exception("Error In Sending " +
           "Command To Server:" & vbCrLf & ex.Message)
    End Try
End Function

Check Server Response

VB
'POP3
'The pop3 server will return "+OK" when command success, 
'otherwise it will return "-ERR".
    Private Function CorrectedResponse(ByVal ReceivedBytes() As Byte, _
                        Optional ByRef Message As String = "") As Boolean
        Dim strText As String = Encoding.ASCII.GetString(ReceivedBytes)
        Message = strText
        RaiseEvent GotResponse(strText)
        If strText.StartsWith("+OK") Then
            Return True
        Else
            Return False
        End If
    End Function
'SMTP
'The SMTP server will return a message with a three-bit-digital 
'for each command. The first bit indicates whether the 
'command is successful or failed as show below

    Private Function CorrectedResponse(ByVal ReceivedBytes() As Byte, _
                       Optional ByRef Message As String = "") As Boolean
        'The first digital of the three digitals in 
        'response message indicates as follow:
        '1: command accepted, waiting for confirm
        '2: command executed
        '3: command accepted, waiting for more information
        '4: command refused
        '5: command failed
        Dim strText As String = Encoding.ASCII.GetString(ReceivedBytes)
        Message = strText
        RaiseEvent GotResponse(strText)
        Select Case strText.Substring(0, 1)
            Case 1, 2, 3
                Return True
            Case 4, 5
                Return False
            Case Else
                Return False
        End Select
    End Function

Commands in POP3 and SMTP

Here I'll just show you two session samples with a mail server using Microsoft Exchange. The mail class calls the SendCommand() method and the CorrectedResponse() method to send commands to the server and check the command execution results. You can find more information about the POP3 and SMTP protocol standards on the Web.

The bold string indicates it's a command:

==SMTP===
220 Microsoft ESMTP MAIL Service, Version: 5.0.2195.6713 ready at 
Fri, 13 Aug 2004 11:12:22 +0800 
helo 
250 mail.cyberrs2.com Hello [192.168.101.52] 
mail from:test@test.com 
250 2.1.0 test@test.com ....Sender OK 
rcpt to:abc@abc.com 
250 2.1.5 abc@abc.com 
data 
354 Start mail input; end with <CRLF>.<CRLF> 
subject:test test smtp & pop3 
. 
250 2.6.0 <MAILiAXL21xDenYPnDd00022f02> Queued mail for delivery 
quit 
221 2.0.0 Service closing transmission channel
==POP3==
+OK Microsoft Exchange Server 2003 POP3 6.5.6944.0 (mail.cyberrs2.com)
user test
+OK 
pass ****** 
+OK User successfully logged on. 
stat 
+OK 1 414 
list
+OK 1 414 
1 414 
. 
retr 1 
+OK 
Received: Microsoft SMTPSVC(5 .0.2195.6713); 
Fri, 13 Aug 2004 11:12:45 +0800 subject:test From: test@test.com
Bcc: 
Return-Path: test@test.com
Message-ID: <MAILiAXL21xDenYPnDd00022f02> 
X-OriginalArrivalTime: 13 Aug 2004 03:13:00.0356 (UTC) 
FILETIME=[7051D840:01C480 E3]
Date: 13 Aug 2004 11:13:00 +0800 
test smtp & pop3 
.
dele 1 
+OK 
quit 
+OK Microsoft Exchange Server 2003 POP3 6.5.6944.0

How to use the QMailClient Class

VB
'Get mail list from serverrDim MailReceiver As QMailClient.POP3Client
MailReceiver = New POP3Client        
MailReceiver.RemoteServerAddress = "pop3.163.com"
MailReceiver.UserName = "xxx"
MailReceiver.Password = "yyyy"
'Optional, please set this TRUE when you are under firewall or 
'using antivirus software which will scan incoming and outgoing mails.
MailReceiver.IncreaseNetworkCompatible = True  
If MailReceiver.Login() = False Then
  MessageBox.Show("Login failed", "Error", _
     MessageBoxButtons.OK, MessageBoxIcon.Error)
  Exit Sub
End If

If Not arrList Is Nothing Then
  arrList.Clear()
  arrList = MailReceiver.GetMailList(True)
  MailReceiver.Quit()
End Iff
'Get a mail from server according to the 
'mail index which can be obtained in mail list
Dim MailReceiver As QMailClient.POP3Client
MailReceiver = New POP3Client
MailReceiver.RemoteServerAddress = "pop3.163.com"
MailReceiver.UserName = "xxx"
MailReceiver.Password = "yyyy"
MailReceiver.IncreaseNetworkCompatible = True  
Try
  MailReceiver.Login()
  'Mail Index, it can be obtain from mail list(start from 1)
  Mail = MailReceiver.RetrieveMail(MailIndex)   
Catch ex As Exception
  MessageBox.Show(ex.Message, "Error", _
       MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
  MailReceiver.Quit()


End Try
'NOTES: The Retrievemail() method has two overloads which will return 
'a QMailClient.EMail object or the source code string of the mail,
'The EMail object can decode the mail automatically and 
'support many mail content type such as multipart/mixed,
'multipart/related and multipart/report.
'If you want to use your own mail decoder then just call the overload 
'function which only return mail source code (string).
'Show mail on a form or a web page
'NOTES: The code below is not assured to run because it needs some 
'form controls, here just show an example.
'The Email.body contains the plain text mail content and the 
'Email.bodyHTML contains the source HTML code of the mail 
'content if the mail is formatted in HTML
    Private Sub ShowMail()
>>        Me.lblMailDate.Text = "DATE: " & Mail.Date
>>        Me.lblMailFrom.Text = "FROM: " & Mail.From
>>        Me.lblMailSubject.Text = "SUBJECT: " & Mail.Subject
>>        Me.lblMailTo.Text = "TO: " & Mail.To
>>        'Write a temp file to show HTML mail
>>        If Mail.BodyContentType = EMail.ContentType.MultipartAlternative Then
>>            Dim file As New FileStream(FolderTmp & "tmp.html", _
                             FileMode.Create, FileAccess.Write, FileShare.None)
>>            Dim a As Encoding = Encoding.GetEncoding("gb2312")
>>
>>            file.Write(a.GetBytes(Mail.BodyHTML), 0, _
                                         a.GetByteCount(Mail.BodyHTML))
>>            file.Close()
>>            Me.rtxtContent.Text = Mail.Body
>>            Me.tbtnHTML.Enabled = True
>>        ElseIf Mail.BodyContentType = EMail.ContentType.MultipartRelated Then
>>            Dim file As New FileStream(FolderTmp & "tmp.html", _
                          FileMode.Create, FileAccess.Write, FileShare.None)
>>            Dim a As Encoding = Encoding.GetEncoding("gb2312")
>>
>>            Dim att As MailAttachment
>>            Dim strBody As String = Mail.BodyHTML
>>            For Each att In Mail.Attachments
>>                If att.ContentID <> "" Then
>>                    strBody = strBody.Replace("cid:" & att.ContentID, _
                                                            att.FileName)
>>                    att.SaveToFile(FolderTmp & att.FileName)
>>                End If
>>            Next
>>
>>            file.Write(a.GetBytes(strBody), 0, a.GetByteCount(strBody))
>>            file.Close()
>>            Me.rtxtContent.Text = Mail.Body
>>            Me.tbtnHTML.Enabled = True
>>        Else
>>            Me.rtxtContent.Text = Mail.Body
>>            Me.tbtnHTML.Enabled = False
>>        End If
>>
>>        If Mail.Attachments.Count <> 0 Then
>>            Dim mailAttach As MailAttachment
>>
>>            For Each mailAttach In Mail.Attachments
>>                'Create a empty file in order to get icon
>>                Dim strExName As String = _
>>                   FileInformation.GetFileExtendedName(mailAttach.FileName)
>>                Dim strmFile As New _
>>                   FileStream(FolderTmp & "ico." & strExName, _
>>                                                          FileMode.Create)
>>                strmFile.Close()
>>
>>                Dim fsi As System.IO.FileSystemInfo
>>                fsi = New FileInfo(FolderTmp & "ico." & strExName)
>>                imgFileIcons.Images.Add(IconExtractor.GetSmallIcon(fsi))
>>                lstvAttachments.Items.Add(_
                            SysInfomation.GetFileNameFromFilePath(_
                                               mailAttach.FileName), _
                                               imgFileIcons.Images.Count - 1)
>>            Next
>>            Me.grpbxAttach.Visible = True
>>        End If
>>    End Sub
'Sending a mail
>>>>       Dim mailSend As New QMailClient.EMail
                       'Use ";" to splite multi-receivers
>>>>       mailSend.To = "abc@bcd.com;dd@dd.com"   
>>>>       mailSend.Cc = "cc@dd.com"
>>>>       mailSend.Subject = "test"
>>>>       mailSend.Body = "test1"
>>>>       mailSend.From = "abc@abc.com"
>>>>              
>>>>       Dim mailClient As New SMTPClient
>>>>       mailClient.RemoteServerAddress = "pop3.163.com"
>>>>             
>>>>       mailClient.IncreaseNetworkCompatible = True
>>>>
>>>>       If mailClient.Connect = True Then
>>>>                    
>>>>           mailClient.UserName = "user"
>>>>           mailClient.Password = "pass"
>>>>                      
>>>>           If mailClient.AuthLogin = False Then
>>>>               MessageBox.Show("Authentication failed", _
                                   "Error", MessageBoxButtons.OK, _
                                              MessageBoxIcon.Error)
>>>>                            
>>>>               Exit Sub
>>>>           End If
>>>>               
>>>>                   
>>>>           mailClient.SendMail(mailSend)
>>>>          
>>>>           mailClient.Quit()
>>>>
>>>>           mailClient = Nothing
>>>>       End If

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionpop3 massege login failed With email Gmail [modified] Pin
khalidys24-Aug-09 2:13
khalidys24-Aug-09 2:13 
AnswerRe: pop3 massege login failed With email Gmail Pin
RezTiNpeaCe10-Feb-10 14:29
RezTiNpeaCe10-Feb-10 14:29 
GeneralThank you, Tony Pin
Domenican16-Jul-09 20:01
Domenican16-Jul-09 20:01 
GeneralAttachments Pin
alterjo6-Jul-09 22:07
alterjo6-Jul-09 22:07 
GeneralRe: Attachments Pin
Santoshbalid2-Nov-12 2:40
Santoshbalid2-Nov-12 2:40 
GeneralBug in POP3Client.SendCommand (Possible Infinite Loop) Pin
dequadin25-Jun-09 2:49
dequadin25-Jun-09 2:49 
QuestionAtt.ContentID Pin
Ruandv4-Jun-09 21:49
Ruandv4-Jun-09 21:49 
Questioncan not retrieve Attachments Pin
Ruandv4-Jun-09 2:35
Ruandv4-Jun-09 2:35 
Hi. Cry | :((
I am sending a mail from gmail to my work account where i do receive the email and i can see the body,subject,to and other info but it does not display my attachments.
When i download the email to my outlook then i can see the attachments. Can anyone please help me with an answer to that. Herewith the code and header of the email that i retrieve.

Please can you help me with an answer. I went through all the posts of this piece of code and i dont seem to get the answer.

Private Sub cmdDownload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdDownload.Click
        Dim att As EMail.MailAttachmentCollection
        Dim arrList As ArrayList = Nothing
        'Connect to the Pop3Server
        Pop3C = New QMailClient.POP3Client
        If POPConnect() = False Then Exit Sub
        With Pop3C
            'set the MailListvalue as per code on your page
            arrList = .GetMailList(True)
            'if there are mail in the mailList then download it.
            If arrList.Count > 0 Then
                For ix As Integer = 0 To (arrList.Count - 1)
                    'loop through all the emails 
                    Email = arrList(ix)
                    'Check if there is an attachment and if so then save it.
                    MsgBox(Email.From)
                    MsgBox(Email.Date)
                    MsgBox(Email.Subject)
                    MsgBox(Email.Attachments.Count) 'This always reflect as 0
                    For Each att In Email.Attachments
                        'attachemtns to be save to a location but the code does not even

                    Next
                Next
            End If
            .Quit()
            .CloseForcedly()
        End With
    End Sub



-----------------------------------------
HEADER:Start Confused | :confused:
-----------------------------------------
"Return-Path: <ruandv@gmail.com>
Received: from localhost (localhost [127.0.0.1])
by quire.workforce.co.za (Cyrus v2.3.9-Gentoo) with LMTPA;
Thu, 04 Jun 2009 14:07:11 +0200
X-Sieve: CMU Sieve 2.3
Received: from localhost (localhost [127.0.0.1])
by quire.workforce.co.za (Postfix) with ESMTP id DEC321F0001;
Thu, 4 Jun 2009 14:07:11 +0200 (SAST)
X-Virus-Scanned: by amavisd-new at workforce.co.za
Received: from quire.workforce.co.za ([127.0.0.1])
by localhost (quire.workforce.co.za [127.0.0.1]) (amavisd-new, port 10024)
with ESMTP id YQEcaKy4dv-g; Thu, 4 Jun 2009 14:07:09 +0200 (SAST)
Received: from localhost (localhost [127.0.0.1])
by quire.workforce.co.za (Postfix) with ESMTP id 7EDF668335E;
Thu, 4 Jun 2009 14:07:08 +0200 (SAST)
Received: from ironport.workforce.co.za (nighthawk.datapro.co.za [196.41.2.10])
by quire.workforce.co.za (Postfix) with ESMTP id 391B768330B
for <ruan@workforceinfotech.co.za>; Thu, 4 Jun 2009 14:07:08 +0200 (SAST)
Received: from mail-fx0-f206.google.com ([209.85.220.206])
by ironport.workforce.co.za with ESMTP; 04 Jun 2009 14:07:06 +0200
X-IronPort-Anti-Spam-Filtered: true
X-IronPort-Anti-Spam-Result: As4HAIdVJ0rRVdzOgWdsb2JhbACCJS0UlHU/AQEWIqUggRSQZQEDAgSECAU
X-IronPort-AV: i="4.41,305,1241388000";
d="ini'?scan'208"; a="5726338:sNHT77609030"
Received: by fxm2 with SMTP id 2so642339fxm.39
for <ruan@workforceinfotech.co.za>; Thu, 04 Jun 2009 05:07:03 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=gamma;
h=domainkey-signature:mime-version:received:date:message-id:subject
:from:to:content-type;
bh=UYb1A9hxaIODzxWaxs5ZdSPYEnhoGYO0dMlS8Xx//H8=;
b=qVg3JBr7l41rwa5NZdd8r+nvqClGzfELR8UyOgkYGdX4evmWq//lT3i+0siubnl6Zk
0lsTEUZPQ+LRzQ/HK329zKjoDnsUcTPB6xYQtT196AvmEoj6ZL66BR7gn78ig0MszyxX
3fLfu9ZOL3Omf6MnWrJ66oahKmStbehm33w50=
DomainKey-Signature: a=rsa-sha1; c=nofws;
d=gmail.com; s=gamma;
h=mime-version:date:message-id:subject:from:to:content-type;
b=JLEt0gvjB66KiLXbtmDCxe2qzehtESbHsM4ELzDQlvnUV6iu4j3cHrc8pZ3yK1ak2n
16g/S7Jh32vD7IgpyHGty33B2Vh5KOgZ5e+gudah8QogqMC6vfFpjrBM0oUVM0pnr84x
ikFJ0ncPNRFO1HlxuxABFRc+n9paOODeAOVNE=
MIME-Version: 1.0
Received: by 10.223.126.66 with SMTP id b2mr1262103fas.18.1244117220734; Thu,
04 Jun 2009 05:07:00 -0700 (PDT)
Date: Thu, 4 Jun 2009 14:07:00 +0200
Message-ID: <f19839b30906040507w79564f99k96c29393cfe29d6e@mail.gmail.com>
Subject: 2attachments
From: Ruan de Villiers <ruandv@gmail.com>
To: ruan@workforceinfotech.co.za
Content-Type: multipart/mixed; boundary=001636c5a43500396d046b849da8
X-Kolab-Scheduling-Message: FALSE
-----------------------------------------
END Confused | :confused:
-----------------------------------------
AnswerRe: can not retrieve Attachments Pin
TonyTonyQ4-Jun-09 5:26
professionalTonyTonyQ4-Jun-09 5:26 
AnswerRe: can not retrieve Attachments Pin
Ruandv4-Jun-09 20:42
Ruandv4-Jun-09 20:42 
QuestionCannot save attatchemt to my server. It is trying to save to a strange path... Pin
acowbear13-May-09 8:43
acowbear13-May-09 8:43 
AnswerRe: Cannot save attatchemt to my server. It is trying to save to a strange path... Pin
TonyTonyQ13-May-09 17:48
professionalTonyTonyQ13-May-09 17:48 
GeneralRe: Cannot save attatchemt to my server. It is trying to save to a strange path... Pin
acowbear14-May-09 5:08
acowbear14-May-09 5:08 
GeneralRe: Cannot save attatchemt to my server. It is trying to save to a strange path... Pin
acowbear15-May-09 3:14
acowbear15-May-09 3:14 
QuestionHow do you use the Reply To Pin
thebigo11-Mar-09 19:20
thebigo11-Mar-09 19:20 
GeneralAttachment Pin
Padingt0n3-Mar-09 6:51
Padingt0n3-Mar-09 6:51 
GeneralRe: Attachment Pin
TonyTonyQ3-Mar-09 15:01
professionalTonyTonyQ3-Mar-09 15:01 
QuestionProblem with Plain-Text special characters encoding [modified] Pin
jerzdna23-Jun-08 23:09
jerzdna23-Jun-08 23:09 
AnswerRe: Problem with Plain-Text special characters encoding Pin
Ruuteek2-Oct-08 0:44
Ruuteek2-Oct-08 0:44 
GeneralRe: Problem with Plain-Text special characters encoding Pin
Ruuteek2-Oct-08 2:22
Ruuteek2-Oct-08 2:22 
QuestionUnable to Get this working - please help Pin
Tastic18-Apr-08 23:13
Tastic18-Apr-08 23:13 
QuestionRe: Unable to Get this working - please help Pin
anas010011-Nov-09 4:33
anas010011-Nov-09 4:33 
GeneralGreat Job! Pin
zach_hurst11-Mar-08 16:19
zach_hurst11-Mar-08 16:19 
Generalpop3 Pin
anilshelar457-Mar-08 23:37
anilshelar457-Mar-08 23:37 
QuestionAm getting "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond" error.... Pin
krsk4u6-Mar-08 2:24
krsk4u6-Mar-08 2:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.