最終更新日: 1998年 11月 02日 月曜日
VisualStudio 6.0を使用するようになってMFCでより簡単に、
かつ複雑なプログラムが構築できるようになってきましたが、まだネットワーク関連は簡単
とはいかないようです。とくに、FTP・GOPHER・HTTPはそれぞれのクラスがサ
ポートされ簡単にアクセスできるようになりましたが、SMTPなどのメールサーバーへのア
クセスのためにはいまだにCSocketを通してWindockを使用することになり
ます。
今回、簡単に電子メールを送信するために関数を作成してみました。使用上の注意は、
MFCアプリケーションウィザードでWinsockを使用するオプション付で プロジェクトを作成する |
ことぐらいで、あとはこのリストをカット&ペーストすることで作成できます。本文
中は日本語が使用できるように、サーバーに対してはquoted-printableフォーマットで7ビッ
トテキスト出力をしています。タイトルには日本語がしようできないサーバーもあります。
こうしたサーバーの制限については電子メールサーバー次第ともいえますのでここのサーバー
にあわせて組む必要が有るかもしれません。ここでは基本関数として、かつまたquoted-printable
フォーマット文字列への変換方法についてのサンプルとして掲載しておきます。
同様の方法で非同期Winsock関数を使用しながら同期型の様な形でソケットを
使用できるためPOP3への変更なども簡単に行えることでしょう。
BOOL SendMailMessage(CString szServer,
CString szFrom, CString szTo, CString szSubject, CString szMessage,BOOL
bSilent){
CSock cSock;
CString strResponse;
if (!cSock.Create(szServer, 25))
{
if(bSilent==FALSE)
AfxMessageBox("Could not connect to server");
return FALSE;
}
// Read response
if (cSock.Receive(&strResponse) == SOCKET_ERROR)
{
if(bSilent==FALSE)
cSock.ReportError(cSock.GetLastError());
return FALSE;
}
if (strResponse.Left(3) != _T("220"))
{
CString strError = "ERROR: SMTP
サーバーから正常な応答が返ってきませんでした\r\n";
strError += strResponse;
if(bSilent==FALSE)
AfxMessageBox(strError);
cSock.SendQuit();
return FALSE;
}
cSock.SendHelo(szFrom); // Send "HELO"
if (cSock.Receive(&strResponse) == SOCKET_ERROR)
{
if(bSilent==FALSE)
cSock.ReportError(cSock.GetLastError());
return FALSE;
}
if (strResponse.Left(3) != _T("250"))
{
CString strError = "ERROR:
送信に失敗しました(送信者エラー)\r\n";
strError += strResponse;
if(bSilent==FALSE)
AfxMessageBox(strError);
cSock.SendQuit();
return FALSE;
}
//
cSock.SendFrom(szFrom); // Send "FROM"
if (cSock.Receive(&strResponse) == SOCKET_ERROR)
{
if(bSilent==FALSE)
cSock.ReportError(cSock.GetLastError());
return FALSE;
}
if (strResponse.Left(3) != _T("250"))
{
CString strError = "ERROR:
送信に失敗しました(送信者エラー)\r\n";
strError += strResponse;
if(bSilent==FALSE)
AfxMessageBox(strError);
cSock.SendQuit();
return FALSE;
}
cSock.SendTo(szTo); // Send "RCPT"
if (cSock.Receive(&strResponse) == SOCKET_ERROR)
{
if(bSilent==FALSE)
(cSock.GetLastError());
return FALSE;
}
if (strResponse.Left(3) != _T("250"))
{
CString strError = "ERROR:
送信エラーが発生しました\r\n";
strError += strResponse;
if(bSilent==FALSE)
AfxMessageBox(strError);
cSock.SendQuit();
return FALSE;
}
cSock.SendData(); // Send the "DATA" line
if (cSock.Receive(&strResponse) == SOCKET_ERROR)
{
if(bSilent==FALSE)
cSock.ReportError(cSock.GetLastError());
return FALSE;
}
if (strResponse.Left(3) != _T("354"))
{
CString strError = "ERROR:
送信エラーが発生しました(データ)\r\n";
strError += strResponse;
if(bSilent==FALSE)
AfxMessageBox(strError);
cSock.SendQuit();
return FALSE;
}
cSock.SendMIME
(1,0);
// Send MIME 1.0
cSock.SendContentType ();
// Send Content type
cSock.SendEncodeType ();
// Send Content Encode Type to Quoted-printable
cSock.SendXMailer
("Sample Mail Send Soft"); // Send Mail soft
cSock.SendSubject
(cSock.ConvertQuoted(szSubject)); // Send the
"Subject"
// Message Body
if (cSock.Send(cSock.ConvertQuoted(szMessage)) == SOCKET_ERROR)
{
if(bSilent==FALSE)cSock.ReportError(cSock.GetLastError());
return FALSE;
}
cSock.SendTermination(); // Send the termination
if (cSock.Receive(&strResponse) == SOCKET_ERROR)
{
if(bSilent==FALSE)
cSock.ReportError(cSock.GetLastError());
return FALSE;
}
if (strResponse.Left(3) != _T("250"))
{
CString strError = "ERROR:
送信エラーが発生しました(メッセージ)\r\n";
strError += strResponse;
if(bSilent==FALSE)
AfxMessageBox(strError);
cSock.SendQuit();
return FALSE;
}
cSock.SendQuit();
return TRUE;
}
#ifndef __CLASS_CSOCK__
#define __CLASS_CSOCK__
class CSock : public CSocket {
public:
int Create(LPCTSTR szServer,int nPort,UINT
nSocketPort = 0, int nSocketType = SOCK_STREAM, LPCTSTR lpszSocketAddress = NULL);
int Create(CString sServer ,int nPort,UINT
nSocketPort = 0, int nSocketType = SOCK_STREAM, LPCTSTR lpszSocketAddress = NULL);
public:
int Send(CString s,int nFlags=0);
int Send(LPCTSTR s,int nFlags=0);
public: //
int Receive(CString *s,int nFlags = 0);
void ReportError(int nError);
public: // 文字列変換
CString ConvertQuoted(CString szMessage); //
quoted-printable文字列に変換
//----------------------------------------------------
// Send SMTP Command Messages
public:
int SendHelo(LPCTSTR szHelo,int nFlags = 0);
int SendHelo(CString szHelo,int nFlags = 0);
int SendFrom(LPCTSTR szFrom,int nFlags = 0);
int SendFrom(CString szFrom,int nFlags = 0);
int SendTo (LPCTSTR szTo,int
nFlags = 0);
int SendTo (CString szTo,int
nFlags = 0);
int SendData(int nFlags = 0);
int SendSubject(LPCTSTR szSubject,int
nFlags=0);
int SendSubject(CString szSubject,int
nFlags=0);
int SendMIME(int nMajor,int nMinor,int
nFlags=0);
int SendContentType(int nFlags=0);
// text/plain;
int SendContentType(LPCTSTR szType,int
nFlags=0);
int SendContentType(CString szType,int
nFlags=0);
int SendXMailer(LPCTSTR szXMailer,int
nFlags=0);
int SendXMailer(CString szXMailer,int
nFlags=0);
int SendEncodeType(int nFlags=0);
// quoted-printable
int SendEncodeType(LPCTSTR szType,int
nFlags=0);
int SendEncodeType(CString szType,int
nFlags=0);
int SendTermination(int nFlags = 0);
int SendQuit(int nFlags = 0);
};
CString CSock::ConvertQuoted(CString szMessage){
CString s;
char *buf;
char bf[8];
int i,n;
s = "";
n = szMessage.GetLength();
buf = (char*)malloc( n+20 );
strcpy(buf,LPCTSTR(szMessage) );
for(i=0;i<n;i++){
int b;
b = (int)(buf[i] & 0x00ff);
if( (b<33)||(b>127)||(b==61) ){
s += "=";
wsprintf(bf,"%.2x",b);
s += bf;
}else{
wsprintf(bf,"%c",b);
s += bf;
}
}
free(buf);
return s;
}
int CSock::Create(CString sServer,int nPort,UINT nSocketPort, int nSocketType, LPCTSTR
lpszSocketAddress){
return( Create(
LPCTSTR(sServer),nPort,nSocketPort,nSocketType,lpszSocketAddress) );
}
int CSock::Create(LPCTSTR szServer,int nPort,UINT nSocketPort, int nSocketType, LPCTSTR
lpszSocketAddress){
int n=CSocket::Create(nSocketPort,nSocketType,lpszSocketAddress);
if(n==0)return n;
return( CSocket::Connect(szServer,nPort) );
}
void CSock::ReportError(int nError){
CString strError;
strError.LoadString(nError);
AfxMessageBox(strError);
}
int CSock::Receive(CString *s,int nFlags){
static char buf[1024];
ZeroMemory(buf,1024);
int n = CSocket::Receive(buf,1024,nFlags);
*s = buf;
return n;
}
//------------------------------------------
int CSock::SendTermination(int nFlags){
return ( Send("\r\n.\r\n") );
}
//------------------------------------------
int CSock::SendEncodeType(int nFlags){
return(SendEncodeType("quoted-printable") );
}
int CSock::SendEncodeType(LPCTSTR szType,int nFlags)
{
CString strCommand = "Content-Transfer-Encoding: ";
strCommand += szType;
strCommand += "\r\n";
return( Send(strCommand,nFlags) );
}
int CSock::SendEncodeType(CString szType,int nFlags)
{
CString strCommand = "Content-Transfer-Encoding: ";
strCommand += szType;
strCommand += "\r\n";
return( Send(strCommand,nFlags) );
}
//------------------------------------------
int CSock::SendMIME(int nMajor,int nMinor,int nFlags){
CString strCommand = "MIME-Version: ";
char buf[80];
wsprintf(buf,"%d.%d",nMajor,nMinor);
strCommand += buf;
strCommand += "\r\n";
return( Send(strCommand,nFlags) );
}
//------------------------------------------
int CSock::SendContentType(int nFlags){
return( SendContentType("text/plain;") );
}
int CSock::SendContentType(LPCTSTR szType,int nFlags)
{
CString strCommand = "Content-Type: ";
strCommand += szType;
strCommand += "\r\n";
return( Send(strCommand,nFlags) );
}
int CSock::SendContentType(CString szType,int nFlags)
{
CString strCommand = "Content-Type: ";
strCommand += szType;
strCommand += "\r\n";
return( Send(strCommand,nFlags) );
}
//------------------------------------------
int CSock::SendXMailer(LPCTSTR szXMailer,int nFlags)
{
CString strCommand = "X-Mailer: <";
strCommand += szXMailer;
strCommand += ">\r\n";
return( Send(strCommand,nFlags) );
}
int CSock::SendXMailer(CString szXMailer,int nFlags)
{
CString strCommand = "X-Mailer: <";
strCommand += szXMailer;
strCommand += ">\r\n";
return( Send(strCommand,nFlags) );
}
//------------------------------------------
int CSock::SendSubject(LPCTSTR szSubject,int nFlags)
{
CString strCommand = "Subject: ";
strCommand += szSubject;
strCommand += "\r\n";
return( Send(strCommand,nFlags) );
}
int CSock::SendSubject(CString szSubject,int nFlags)
{
return( SendSubject(LPCTSTR(szSubject),nFlags) );
}
//------------------------------------------
int CSock::SendTo(LPCTSTR szTo,int nFlags)
{
CString strCommand = "RCPT TO:<";
strCommand += szTo;
strCommand += ">\r\n";
return( Send(strCommand,nFlags) );
}
int CSock::SendTo(CString szTo,int nFlags)
{
return( SendTo(LPCTSTR(szTo),nFlags) );
}
//---------------------------------------------
int CSock::SendFrom(LPCTSTR szFrom,int nFlags)
{
CString strCommand = "MAIL FROM:<";
strCommand += szFrom;
strCommand += ">\r\n";
return( Send(strCommand,nFlags) );
}
int CSock::SendFrom(CString szFrom,int nFlags)
{
return( SendFrom( LPCTSTR(szFrom),nFlags) );
}
//---------------------------------------------
int CSock::SendHelo(LPCTSTR szHelo,int nFlags)
{
CString strCommand = "HELO ";
if( strchr(szHelo,'@')==0) strCommand += szHelo;
else strCommand += (strchr(szHelo,'@')+1);
strCommand += "\r\n";
return( Send(strCommand,nFlags) );
}
int CSock::SendHelo(CString szHelo,int nFlags)
{
return( SendHelo( LPCTSTR(szHelo),nFlags) );
}
//---------------------------------------------
int CSock::SendData(int nFlags){
return( Send("DATA\r\n",nFlags) );
};
int CSock::SendQuit(int nFlags){
return( Send("QUIT\r\n",nFlags) );
};
int CSock::Send(CString s,int nFlags){
return( Send(LPCTSTR(s),nFlags) );
};
int CSock::Send(LPCTSTR s,int nFlags){
return( CSocket::Send(s,strlen(s),nFlags) );
};
#endif // __CLASS_CSOCK__
Copyright (C) Kitaro 1998