Long Explanation, But A Basic VB6/Winsock/SMTP Question 
Author Message
 Long Explanation, But A Basic VB6/Winsock/SMTP Question

Like the subject says, I'm long-winded but the question is actually
simple. I downloaded RFC2821, I found sample code and adapted it, and
I can now send an e-mail out of Visual Basic using SMTP. The problem
is that I can send it to only one recipient. No multiple "To"s, no
"Cc" and no "Bcc". Here's the relevant sample code (most variables
were populated previous to getting to the DataArrival event):

' These are the SMTP-related variables and enumerations
Private Enum SMTP_State
    MAIL_CONNECT
    MAIL_HELO
    MAIL_FROM
    MAIL_RCPTTO
    MAIL_DATA
    MAIL_DOT
    MAIL_QUIT
End Enum
Private m_State As SMTP_State

' These are all the other various variables needed to make this work
Private sSenderName As String
Private sSenderID As String
Private sRecipName() As String
Private sRecipID() As String
Private sRecipType() As String
Private iRecipNum As Integer
Private sSubject As String
Private sBody As String

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)

    Dim strServerResponse As String
    Dim strResponseCode As String
    Dim strDataToSend As String

    Winsock1.GetData strServerResponse
    strResponseCode = Left(strServerResponse, 3)
    '
    'Only these three codes tell us that previous
    'command accepted successfully and we can go on
    '
    If strResponseCode = "250" _
        Or strResponseCode = "220" _
        Or strResponseCode = "354" Then
            Select Case m_State
                Case MAIL_CONNECT
                    m_State = MAIL_HELO
                    strDataToSend = Trim$(sSenderID)
                    strDataToSend = Left$(strDataToSend, _

                    Winsock1.SendData "HELO " & strDataToSend & vbCrLf
                Case MAIL_HELO
                    m_State = MAIL_FROM
                    Winsock1.SendData "MAIL FROM:" _
                                    & Trim$(sSenderID) _
                                    & vbCrLf
                Case MAIL_FROM
                    m_State = MAIL_RCPTTO
                    For iRecipNum = 0 To UBound(sRecipID)
                        Winsock1.SendData "RCPT TO:" _
                                        & sRecipID(iRecipNum) _
                                        & vbCrLf
                    Next
                Case MAIL_RCPTTO
                    m_State = MAIL_DATA
                    Winsock1.SendData "DATA" & vbCrLf
                Case MAIL_DATA
                    m_State = MAIL_DOT
                    Winsock1.SendData "From: " _
                                    & sSenderName _
                                    & "<" _
                                    & sSenderID _
                                    & ">" _
                                    & vbCrLf
                    For iRecipNum = 0 To UBound(sRecipID)
                        Select Case UCase(sRecipType(iRecipNum))
                            Case "TO"
                                Winsock1.SendData "To: " _
                                       & sRecipName(iRecipNum) _
                                       & "<" _
                                       & sRecipID(iRecipNum) _
                                       & ">" _
                                       & vbCrLf
                            Case "CC"
                                Winsock1.SendData "Cc: " _
                                       & sRecipName(iRecipNum) _
                                       & "<" _
                                       & sRecipID(iRecipNum) _
                                       & ">" _
                                       & vbCrLf
                            Case "BCC"
                            ' Not doing anything sends a blind copy
                        End Select
                    Next
                    Winsock1.SendData "Subject: " _
                                    & sSubject _
                                    & vbCrLf _
                                    & vbCrLf
                    Winsock1.SendData sBody _
                                    & vbCrLf _
                                    & vbCrLf
                    Winsock1.SendData "." & vbCrLf
                Case MAIL_DOT
                    m_State = MAIL_QUIT
                    Winsock1.SendData "QUIT" & vbCrLf
                Case MAIL_QUIT
                    Winsock1.Close
            End Select
    Else
        Winsock1.Close
        If Not m_State = MAIL_QUIT Then
            MsgBox "SMTP Error: " & strServerResponse, _
                    vbInformation, "SMTP Error"
            Unload Me
            End
        Else
            Unload Me
            End
        End If
    End If
End Sub

*****************************************************************************

I put a bunch of Debug.Print statements in, and here are my results:

HELO allen




DATA



Subject: How About This?
Larry Brown and I will stay, but everyone else will go.
.
QUIT

Does anyone have any clues why only the first recipient gets the
e-mail? It shows up with the FROM, TO and CC fields populated
correctly on that one copy, but that's it. As always, any help would
be appreciated.

John Calahan



Tue, 26 Oct 2004 05:16:20 GMT  
 Long Explanation, But A Basic VB6/Winsock/SMTP Question


Wed, 18 Jun 1902 08:00:00 GMT  
 Long Explanation, But A Basic VB6/Winsock/SMTP Question


Quote:
> Like the subject says, I'm long-winded but the question is actually
> simple. I downloaded RFC2821, I found sample code and adapted it, and
> I can now send an e-mail out of Visual Basic using SMTP. The problem
> is that I can send it to only one recipient. No multiple "To"s, no
> "Cc" and no "Bcc". Here's the relevant sample code (most variables
> were populated previous to getting to the DataArrival event):

(I went through this for nothing, but go ahead and read it all, it'll teach
you something about SMTP, offtopic as that is.)  Scroll down to my comments
in the code to skip the SMTP stuff.

I'm writing something similar, but from the ground up, without the framework
you have here.  I don't feel like tearing the code apart, so I'm going to
tell you what needs done and where, but not how.

The "To", "Cc", "Bcc" and "Subject" fields are simply artifacts of email
programs, they have nothing to do with the way that email is actually sent.
So all you have to do is send a "RCPT TO:" command for each email address
you want to send to.  You should also include "Cc:" or "To:" statements
inside the body of the message, otherwise they will all be Bcc's by default.

Let me demonstrate: here is an example of a potential conversation between
an email client and SMTP server.  There are no comments for the server
responses.

HELO mymail.com                                      <- Logging on to the
SMTP server
mymail.com Pleased to meet you



mail

DATA                                                         <- Tells server
to start recording the email
354 Enter mail, end with "." on a line by itself

of the email

interpret
Subject: Test Email                                     <- everything up to
the first blank line
                                                                  <- as
header information.
This is a test email
.                                                                 <- Tell
the server to stop recording email
250 2.0.0 g49LP6637850 Message accepted for delivery
QUIT

Notice that if you do not include the To: From: and Subject: statements
inside the email itself, they will be missing from the actual email.  (Some
servers will put "undisclosed recipients" in the To: field if there is none
in the email, but not all.)  This one of the reasons why it is so easy to
forge return email addresses.  The Return-Path: (where the email goes if it
bounces) is generated by the MAIL FROM: command, and is *more* reliable.


statements (one for each address) to the server before sending the DATA

before the first blank line in the email.  To make it a To:, simply change
Cc: to To:

The bare bones of your end of the conversation is:
=======================
HELO
MAIL FROM:
RCTP TO:
DATA

This email has no subject.
.
QUIT
=======================

Do not forget the colons, they are important.  You can play around with it
by telnetting to your ISP's mail server and typing the stuff in by hand.

You do this by going to a DOS prompt and typing:
telnet mail.myisp.com 25

Send yourself a few test emails.  Vary them to see how it works.  Also,
check out rfc 2821 a little better, and maybe read
http://perl.about.com/library/weekly/aa032402a.htm

Scroll down to see where the changes are to be made (two places)

Quote:
> ' These are the SMTP-related variables and enumerations
> Private Enum SMTP_State
>     MAIL_CONNECT
>     MAIL_HELO
>     MAIL_FROM
>     MAIL_RCPTTO
>     MAIL_DATA
>     MAIL_DOT
>     MAIL_QUIT
> End Enum
> Private m_State As SMTP_State

> ' These are all the other various variables needed to make this work
> Private sSenderName As String
> Private sSenderID As String
> Private sRecipName() As String
> Private sRecipID() As String
> Private sRecipType() As String
> Private iRecipNum As Integer
> Private sSubject As String
> Private sBody As String

> Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)

>     Dim strServerResponse As String
>     Dim strResponseCode As String
>     Dim strDataToSend As String

>     Winsock1.GetData strServerResponse
>     strResponseCode = Left(strServerResponse, 3)
>     '
>     'Only these three codes tell us that previous
>     'command accepted successfully and we can go on
>     '
>     If strResponseCode = "250" _
>         Or strResponseCode = "220" _
>         Or strResponseCode = "354" Then
>             Select Case m_State
>                 Case MAIL_CONNECT
>                     m_State = MAIL_HELO
>                     strDataToSend = Trim$(sSenderID)
>                     strDataToSend = Left$(strDataToSend, _

>                     Winsock1.SendData "HELO " & strDataToSend & vbCrLf
>                 Case MAIL_HELO
>                     m_State = MAIL_FROM
>                     Winsock1.SendData "MAIL FROM:" _
>                                     & Trim$(sSenderID) _
>                                     & vbCrLf
>                 Case MAIL_FROM

First Spot:
===========
Quote:
>                     m_State = MAIL_RCPTTO
>                     For iRecipNum = 0 To UBound(sRecipID)
>                         Winsock1.SendData "RCPT TO:" _
>                                         & sRecipID(iRecipNum) _
>                                         & vbCrLf
>                     Next

===========

Quote:
>                 Case MAIL_RCPTTO
>                     m_State = MAIL_DATA
>                     Winsock1.SendData "DATA" & vbCrLf
>                 Case MAIL_DATA
>                     m_State = MAIL_DOT
>                     Winsock1.SendData "From: " _
>                                     & sSenderName _
>                                     & "<" _
>                                     & sSenderID _
>                                     & ">" _
>                                     & vbCrLf

Second Spot:
===========

- Show quoted text -

Quote:
>                     For iRecipNum = 0 To UBound(sRecipID)
>                         Select Case UCase(sRecipType(iRecipNum))
>                             Case "TO"
>                                 Winsock1.SendData "To: " _
>                                        & sRecipName(iRecipNum) _
>                                        & "<" _
>                                        & sRecipID(iRecipNum) _
>                                        & ">" _
>                                        & vbCrLf
>                             Case "CC"
>                                 Winsock1.SendData "Cc: " _
>                                        & sRecipName(iRecipNum) _
>                                        & "<" _
>                                        & sRecipID(iRecipNum) _
>                                        & ">" _
>                                        & vbCrLf
>                             Case "BCC"
>                             ' Not doing anything sends a blind copy
>                         End Select
>                     Next

===========

And acutally, it looks like it's alredy setup to do this.

Looks liek the array sRecipID contains all the email addresses with array
sRecipType type TO being To, type CC being Cc, and no type being Bcc.

- Show quoted text -

Quote:
>                     Winsock1.SendData "Subject: " _
>                                     & sSubject _
>                                     & vbCrLf _
>                                     & vbCrLf
>                     Winsock1.SendData sBody _
>                                     & vbCrLf _
>                                     & vbCrLf
>                     Winsock1.SendData "." & vbCrLf
>                 Case MAIL_DOT
>                     m_State = MAIL_QUIT
>                     Winsock1.SendData "QUIT" & vbCrLf
>                 Case MAIL_QUIT
>                     Winsock1.Close
>             End Select
>     Else
>         Winsock1.Close
>         If Not m_State = MAIL_QUIT Then
>             MsgBox "SMTP Error: " & strServerResponse, _
>                     vbInformation, "SMTP Error"
>             Unload Me
>             End
>         Else
>             Unload Me
>             End
>         End If
>     End If
> End Sub

****************************************************************************
*

- Show quoted text -

Quote:

> I put a bunch of Debug.Print statements in, and here are my results:

> HELO allen




> DATA



> Subject: How About This?
> Larry Brown and I will stay, but everyone else will go.
> .
> QUIT

> Does anyone have any clues why only the first recipient gets the
> e-mail? It shows up with the FROM, TO and CC fields populated
> correctly on that one copy, but that's it. As always, any help would
> be appreciated.

> John Calahan




Tue, 26 Oct 2004 08:14:47 GMT  
 Long Explanation, But A Basic VB6/Winsock/SMTP Question


Wed, 18 Jun 1902 08:00:00 GMT  
 Long Explanation, But A Basic VB6/Winsock/SMTP Question
Oops, added an extra line:

Quote:

the
> mail


Should be:



Got a little happy with the cutnpaste.

oh well.

- jim



Tue, 26 Oct 2004 09:05:22 GMT  
 Long Explanation, But A Basic VB6/Winsock/SMTP Question
Excellent article which has been borrowed for later use. :)
Thank you very much for being so off topic! :))))

Rv!



Fri, 29 Oct 2004 20:26:44 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. winsock ; need some explanations

2. Visual Basic Data type question (UNSIGNED LONGS POSSIBLE??)

3. Visual Basic Data type question (UNSIGNED LONGS POSSIBLE??)

4. VB6 App exits without explanation when using DESKTOPTODEVICE

5. Quick question on VB6 winsock

6. Newbie question--Explanation of SET

7. Need further explanation of Transcender test question RE load balancing

8. VB6, EE: Some questions about the Winsock control.

9. VB6, EE: Some questions about the Winsock control.

10. VB6 and winsock ( newbie question )

11. Winsock Question in VB6

12. VB6, EE: Some questions about the Winsock control.

 

 
Powered by phpBB® Forum Software