Brian
2008-07-01 21:59:33 UTC
Hi all,
I am using Indy components in a web site and have had problems with some
of the email never being received by the receipients which I attribute to
their ISP's SPAM blockers. In an attempt to alleviate the problem, I've rewritten
the code to send the message to each receipient individually instead of putting
the entire list (~130 addresses) in the TO: field. The code I have written
is thus:
class TMailer : public TThread
{
private:
TIdSMTP *mailer;
TIdMessage *mailMsg;
TStringList *addresses;
FILE *fp;
protected:
void __fastcall Execute();
public:
__fastcall TMailer(bool CreateSuspended);
bool __fastcall loadData(String filePath,TIniFile *ini,String subject,String
msg,String replyTo,TStringList *to);
};
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "mailThread.h"
#pragma package(smart_init)
#pragma link "indy60.lib"
//---------------------------------------------------------------------------
__fastcall TMailer::TMailer(bool CreateSuspended) : TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall TMailer::Execute()
{
for(int i=0;i<addresses->Count;i++)
{ mailMsg->Recipients->Clear();
TIdEMailAddressItem *item=mailMsg->Recipients->Add();
item->Address=addresses->Strings[i];
try
{ if(!mailer->Connected())
mailer->Connect(5000);
if(mailer->Connected())
{ mailer->Send(mailMsg);
fprintf(fp,"(%s) message sent successfully to %s\n",Now().FormatString("mm/dd/yy
hh:nn:ss"),addresses->Strings[i]);
}
}
catch(Exception const &e)
{
fprintf(fp,"(%s) %s [%s]\nSubject: %s\n",Now().FormatString("mm/dd/yy
hh:nn:ss"),e.Message,addresses->Strings[i],mailMsg->Subject);
}
}
if(mailer->Connected())
mailer->Disconnect();
fclose(fp);
}
//---------------------------------------------------------------------------
bool __fastcall __fastcall TMailer::loadData(String filePath,TIniFile *ini,String
subject,String msg,String replyTo,TStringList *to)
{ String host,from,fromName,username,password,organization;
mailer=new TIdSMTP(Application);
mailMsg=new TIdMessage(Application);
addresses=new TStringList;
addresses->AddStrings(to);
host=ini->ReadString("Email","Host","");
from=ini->ReadString("Email","From Address","");
fromName=ini->ReadString("Email","From Name","");
username=ini->ReadString("EMail","Username","");
password=ini->ReadString("EMail","Password","");
organization=ini->ReadString("Email","Organization","None Specified");
fp=fopen(String(filePath+"mail.log").c_str(),"a");
if(password=="" || username=="")
mailer->AuthenticationType=atNone;
else
mailer->AuthenticationType=atLogin;
mailer->UseEhlo=true;
mailer->Host=host;
mailer->Username=username;
mailer->Password=password;
mailMsg->AttachmentEncoding="MIME";
mailMsg->ContentType="text/html";
mailMsg->Encoding=meMIME;
mailMsg->Organization=organization;
mailMsg->From->Address=from;
mailMsg->Subject=subject;
mailMsg->Date=Now();
if(replyTo!="")
{ TIdEMailAddressItem *item=mailMsg->ReplyTo->Add();
item->Address=replyTo;
}
mailMsg->Body->Text=msg;
return(true);
}
//---------------------------------------------------------------------------
The code from my 'main' is as follows:
TMailer *mail=new TMailer(true);
bool retval=mail->loadData(filePath,ini,subject,msg,replyTo,addresses);
if(retval)
mail->Resume();
The problem that I am having, according to the log is that I am receiving
a Socket Error #10093 mixed among the successful messages. The socket error
is referring to a successful WSAStartup not yet being performed. So, I'm
guessing that each time I send the message, TIdSMTP is performing a WSAStartup
and WSACleanup. If that is indeed the case, is there any way around the problem?
Also, this is my first foray into threading - so if I am doing it wrong,
please help me to understand why it's wrong and how I should go about changing
it to be proper.
Thanks for your help.
I am using Indy components in a web site and have had problems with some
of the email never being received by the receipients which I attribute to
their ISP's SPAM blockers. In an attempt to alleviate the problem, I've rewritten
the code to send the message to each receipient individually instead of putting
the entire list (~130 addresses) in the TO: field. The code I have written
is thus:
class TMailer : public TThread
{
private:
TIdSMTP *mailer;
TIdMessage *mailMsg;
TStringList *addresses;
FILE *fp;
protected:
void __fastcall Execute();
public:
__fastcall TMailer(bool CreateSuspended);
bool __fastcall loadData(String filePath,TIniFile *ini,String subject,String
msg,String replyTo,TStringList *to);
};
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "mailThread.h"
#pragma package(smart_init)
#pragma link "indy60.lib"
//---------------------------------------------------------------------------
__fastcall TMailer::TMailer(bool CreateSuspended) : TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall TMailer::Execute()
{
for(int i=0;i<addresses->Count;i++)
{ mailMsg->Recipients->Clear();
TIdEMailAddressItem *item=mailMsg->Recipients->Add();
item->Address=addresses->Strings[i];
try
{ if(!mailer->Connected())
mailer->Connect(5000);
if(mailer->Connected())
{ mailer->Send(mailMsg);
fprintf(fp,"(%s) message sent successfully to %s\n",Now().FormatString("mm/dd/yy
hh:nn:ss"),addresses->Strings[i]);
}
}
catch(Exception const &e)
{
fprintf(fp,"(%s) %s [%s]\nSubject: %s\n",Now().FormatString("mm/dd/yy
hh:nn:ss"),e.Message,addresses->Strings[i],mailMsg->Subject);
}
}
if(mailer->Connected())
mailer->Disconnect();
fclose(fp);
}
//---------------------------------------------------------------------------
bool __fastcall __fastcall TMailer::loadData(String filePath,TIniFile *ini,String
subject,String msg,String replyTo,TStringList *to)
{ String host,from,fromName,username,password,organization;
mailer=new TIdSMTP(Application);
mailMsg=new TIdMessage(Application);
addresses=new TStringList;
addresses->AddStrings(to);
host=ini->ReadString("Email","Host","");
from=ini->ReadString("Email","From Address","");
fromName=ini->ReadString("Email","From Name","");
username=ini->ReadString("EMail","Username","");
password=ini->ReadString("EMail","Password","");
organization=ini->ReadString("Email","Organization","None Specified");
fp=fopen(String(filePath+"mail.log").c_str(),"a");
if(password=="" || username=="")
mailer->AuthenticationType=atNone;
else
mailer->AuthenticationType=atLogin;
mailer->UseEhlo=true;
mailer->Host=host;
mailer->Username=username;
mailer->Password=password;
mailMsg->AttachmentEncoding="MIME";
mailMsg->ContentType="text/html";
mailMsg->Encoding=meMIME;
mailMsg->Organization=organization;
mailMsg->From->Address=from;
mailMsg->Subject=subject;
mailMsg->Date=Now();
if(replyTo!="")
{ TIdEMailAddressItem *item=mailMsg->ReplyTo->Add();
item->Address=replyTo;
}
mailMsg->Body->Text=msg;
return(true);
}
//---------------------------------------------------------------------------
The code from my 'main' is as follows:
TMailer *mail=new TMailer(true);
bool retval=mail->loadData(filePath,ini,subject,msg,replyTo,addresses);
if(retval)
mail->Resume();
The problem that I am having, according to the log is that I am receiving
a Socket Error #10093 mixed among the successful messages. The socket error
is referring to a successful WSAStartup not yet being performed. So, I'm
guessing that each time I send the message, TIdSMTP is performing a WSAStartup
and WSACleanup. If that is indeed the case, is there any way around the problem?
Also, this is my first foray into threading - so if I am doing it wrong,
please help me to understand why it's wrong and how I should go about changing
it to be proper.
Thanks for your help.