Click here to Skip to main content
Click here to Skip to main content

Send mail without specifying an SMTP server

, 12 Apr 2005 Ms-PL
Rate this:
Please Sign up or sign in to vote.
A class derived from CSMTPConnection that queries the MX record for a target domain and uses that to send mail

Overview

Quite frequently, you hear people asking how they can send an email from their applications to a specific email address without prompting the user for a relaying SMTP server. The most commonly suggested solution is to use MAPI and get a list of SMTP servers from the user's registry, but this assumes that the user has configured a MAPI compliant email client on his machine. I always reply with my solution of querying the MX record for the target domain and then SMTP-chatting to that server directly - it's easy to do, it works on any machine and it's also the fastest way to send email (minimum number of SMTP hops).

Starting with VC++ 7, ATL includes the CSMTPConnection class which lets you send mail, provided you give it an SMTP server to connect to. I derived a class (CSMTPConnection2) from CSMTPConnection which lets you pass in the target domain name directly and the class queries the MX records using the default DNS on the client machine, gets a list of SMTP servers (depending on the number of MX records returned) and connects to the first SMTP server that works okay. The only visible change is to the Connect method, and even for the Connect method, the method signature remains the same. The first parameter (an LPCTSTR) now represents the target domain name instead of the SMTP hostname. So it should be pretty easy to modify your existing code. Just change all references to CSMTPConnection in your code to CSMTPConnection2 and you are done.

Using the class

  • #include the header file for the class

    #include "smtpconnection2.h"

    The header file includes a #pragma linker directive to include Dnsapi.lib

  • Use the CSMTPConnection2 class just as you would use the CSMTPConnection class (it's assumed that CoInitialize has been called prior to invoking and using this class)

    CMimeMessage msg;
    msg.SetSender("nish@somedomain.com");
    msg.SetSenderName("Nishter");
    msg.AddRecipient("someone@vsnl.com");
    
    //Optional
    msg.SetSubject("Hello World");
    msg.AddText("Hmmm, this should work fine!");
    //msg.AttachFile("some file path");
    
    CSMTPConnection2 conn;
    //You need to specify the domain name of the recipient email address
    if(conn.Connect("vsnl.com"))
    {
        if( conn.SendMessage(msg) == TRUE )
            std::cout << "Mail sent successfully" << std::endl;
        conn.Disconnect();    
    }
    

Class requirements

  • You'll need VC++ 7 or above (for the ATL classes)

  • This code will run only on Windows 2000 or later (because of the DNS API that's used to query the MX record)

  • You do not need MFC (the CString that's used is shared between MFC/ATL and I specifically used CSimpleArray instead of an MFC array class)

Limitation

Note that, because the class looks up the MX record and SMTPs directly into the mail server for each domain name, you cannot use this class to send mails to multiple-domains in one go.

Source listings

Header file

/*
    Copyright(C) Nishant Sivakumar (nish#voidnish.com)
    Please maintain this copyright notice if you distribute this file
    in original or modified form.
*/

#pragma once
#include <atlsmtpconnection.h>
#include <Windns.h>

#pragma comment(lib,"Dnsapi.lib")

class CSMTPConnection2 : public CSMTPConnection
{
public:    
    BOOL Connect(LPCTSTR lpszHostDomain, DWORD dwTimeout = 10000) throw();
private:
    void _GetSMTPList(LPCTSTR lpszHostDomain, CSimpleArray<CString>& arrSMTP);
}; 

Cpp file

/*
    Copyright(C) Nishant Sivakumar (nish#voidnish.com)
    Please maintain this copyright notice if you distribute this file
    in original or modified form.
*/

#include "StdAfx.h"
#include "smtpconnection2.h"

BOOL CSMTPConnection2::Connect(LPCTSTR lpszHostDomain, 
                               DWORD dwTimeout /*= 10000*/) throw()
{
    CSimpleArray<CString> arrSMTP;
    _GetSMTPList(lpszHostDomain, arrSMTP);
    for(int i=0; i<arrSMTP.GetSize(); i++)
    {
        if(CSMTPConnection::Connect(arrSMTP[i], dwTimeout) == TRUE)
            return TRUE;
    }
    return FALSE;
}

void CSMTPConnection2::_GetSMTPList(LPCTSTR lpszHostDomain, 
                                   CSimpleArray<CString>& arrSMTP)
{
    PDNS_RECORD pRec = NULL;
    if(DnsQuery(lpszHostDomain, DNS_TYPE_MX, DNS_QUERY_STANDARD,
        NULL, &pRec, NULL) == ERROR_SUCCESS)
    {
        PDNS_RECORD pRecOrig = pRec;
        while(pRec)
        {
            if(pRec->wType == DNS_TYPE_MX)
                arrSMTP.Add(pRec->Data.MX.pNameExchange);
            pRec = pRec->pNext;
        }
        DnsRecordListFree(pRecOrig,DnsFreeRecordList);
    }
} 

Conclusion

As usual, feedback is welcome and appreciated whether it's constructive or not.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

Nish Sivakumar

United States United States
Nish is a real nice guy who has been writing code since 1990 when he first got his hands on an 8088 with 640 KB RAM. Originally from sunny Trivandrum in India, he has been living in various places over the past few years and often thinks it’s time he settled down somewhere.
 
Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site - www.voidnish.com where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff - blog.voidnish.com.
 
Nish loves reading Science Fiction, P G Wodehouse and Agatha Christie, and also fancies himself to be a decent writer of sorts. He has authored a romantic comedy Summer Love and Some more Cricket as well as a programming book – Extending MFC applications with the .NET Framework.
 
Nish's latest book C++/CLI in Action published by Manning Publications is now available for purchase. You can read more about the book on his blog.
 
Despite his wife's attempts to get him into cooking, his best effort so far has been a badly done omelette. Some day, he hopes to be a good cook, and to cook a tasty dinner for his wife.

Comments and Discussions

 
GeneralMy vote of 5 Pinmemberzriniadhi13-Mar-12 2:09 
QuestionError 300 - CSMTP_COMMAND_MAIL_FROM PinmemberAlexEvans18-Jun-11 12:21 
GeneralSend email to multiple recipients who don't belong to the same domain PinmemberD.Lakshmankumar7-Jan-10 19:03 
GeneralRe: Send email to multiple recipients who don't belong to the same domain Pinmemberdaluu9-Oct-10 19:11 
GeneralRe: Send email to multiple recipients who don't belong to the same domain PinmvpNishant Sivakumar11-Oct-10 1:55 
Generaldebug assertion failed notifications Pinmembereugene pinsky17-Aug-09 8:00 
GeneralRe: debug assertion failed notifications [modified] PinmemberBEDEK335-Mar-10 11:32 
GeneralSend without smtp server [modified] PinmemberDipak V Bava28-Feb-09 10:02 
GeneralRe: Send without smtp server PinmemberElmue24-Apr-09 7:11 
Hello
 
Your links are dead.
 
Why don't you post the URL to the page where this DLL comes from ?
 
http://dvgoswami.googlepages.com
 
Elmü
GeneralRe: Send without smtp server PinmemberDipak V Bava24-Apr-09 7:32 
GeneralRe: Send without smtp server Pinmemberdaluu16-Oct-10 20:32 
QuestionWhat about VC++ 2008? PinmemberMember 31360566-Feb-09 22:55 
AnswerRe: What about VC++ 2008? PinmemberDave Calkins28-Feb-09 3:45 
GeneralRe: What about VC++ 2008? PinmemberJanma16-May-10 21:12 
GeneralRe: What about VC++ 2008? Pinmemberdaluu9-Oct-10 19:16 
GeneralUseful article Pinmemberom7-Jan-09 12:33 
QuestionCOM and ActiveX implementation? Pinmemberdaluu1-Nov-08 19:40 
General.NET alternative [modified] Pinmemberdaluu3-Oct-08 20:25 
GeneralQuite useless code! PinmemberElmue17-Jul-08 11:48 
Generalatlsmtpconnection.h PinmembertheCPkid28-Jun-08 4:06 
GeneralProps to Nish Pinmemberbvaghani26-Jan-08 16:31 
Generalrename Connect to ConnectDomain PinmemberHerbert Yu29-Nov-07 10:29 
GeneralRe: rename Connect to ConnectDomain PinmemberYogesh P. Dhakad13-Jan-08 3:03 
GeneralNot working with all providers [modified] PinmemberManthis18-Nov-07 23:46 
GeneralWorks for me on hotmail.com PinmemberHerbert Yu29-Nov-07 9:45 
GeneralRe: Not working with all providers PinmemberMunahid28-Sep-09 22:47 
QuestionMail subject not working PinmemberManthis18-Nov-07 22:52 
AnswerRe: Mail subject not working PinmemberHerbert Yu29-Nov-07 9:35 
GeneralSecurity PinmemberMike Booker18-Sep-07 15:57 
GeneralRe: Security PinmemberHerbert Yu29-Nov-07 9:37 
GeneralVirus detection Pinmembernat2kus21-May-07 10:38 
GeneralRe: Virus detection [modified] Pinmembernat2kus21-May-07 10:44 
GeneralRe: Virus detection PinmemberHerbert Yu28-Nov-07 8:13 
QuestionHTML msg PinmemberRisKhan9-Apr-07 0:49 
AnswerRe: HTML msg Pinmemberdaluu3-Oct-08 20:30 
QuestionDoes anyone have this in vb.net 2005 Pinmemberwultepjo6-Mar-07 20:52 
AnswerRe: Does anyone have this in vb.net 2005 Pinmemberdaluu17-Jul-08 13:35 
GeneralNot Working Pinmembermurtazadhari5-Feb-07 5:13 
GeneralRe: Not Working Pinmemberpascal roca3-Apr-07 4:24 
GeneralMail using VC++ PinmemberSyamlalS31-Dec-06 23:53 
GeneralRe: Mail using VC++ PinmemberRisKhan9-Apr-07 0:52 
GeneralRe: Mail using VC++ PinmemberSyamlalS9-Apr-07 0:56 
GeneralRe: Mail using VC++ Pinmemberxiayuxue12-May-08 23:01 
GeneralAsserting on m_Overlapped.hEvent==0 Pinmemberharryshcoffee17-Dec-06 3:41 
GeneralGreat correction on CSMTPConnection PinmemberHerbert Yu29-Nov-07 9:50 
Generalregarding domain name of the recipient email address Pinmemberchandrashekar T.J13-Dec-06 19:05 
GeneralPlease see [Asserting on m_Overlapped.hEvent==0] above PinmemberHerbert Yu29-Nov-07 9:52 
Questionregarding server name. Pinmembertj_terror12-Dec-06 22:27 
GeneralGiving Exception For Subject PinmemberMahesh Kulkarni22-Nov-06 0:57 
QuestionRequest to compile the file Pinmembersudarshans17-Oct-06 23:59 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141030.1 | Last Updated 12 Apr 2005
Article Copyright 2005 by Nish Sivakumar
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid