C++メールと添付ファイルの送信(転送)


ヘッダファイル
/***********************************************************************
*         
*         (          )
*************************************************************************/
#pragma once
struct sMailInfo //    
{
	char*	m_pcUserName;//         
	char*	m_pcUserPassWord;//         
	char*	m_pcSenderName;//          
	char*	m_pcSender;//        
	char*	m_pcReceiver;//        
	char*	m_pcTitle;//    
	char*	m_pcBody;//      
	char	m_pcIPAddr[32];//    IP
	char*	m_pcIPName;//      (IP      ,     )
	sMailInfo(){memset(this,0,sizeof(sMailInfo));}
};
class CSendMail
{
public:
	CSendMail(void);
	~CSendMail(void);

public:
	bool SendMail(sMailInfo &smailInfo);//    ,               
	void AddFilePath(char * pcFilePath);//               
	void DeleteFilePath(char* pcFilePath);//      ,     
	void DeleteAllPath(void);//         

protected:
	void GetFileName(char* fileName,char* filePath);//             
	void Char2Base64(char* pBuff64,char* pSrcBuff,int iLen);// char     Base64  
	bool  CReateSocket(SOCKET &sock);//  socket  
	bool Logon(SOCKET &sock);//    ,             
	int GetFileData(char* FilePath);//           

	bool SendHead(SOCKET &sock);//     
	bool SendTextBody(SOCKET &sock);//        
	bool SendFileBody(SOCKET &sock);//      
	bool SendEnd(SOCKET &sock);//      
protected:
	CList<char*,char*> m_pcFilePathList;//      

	char  m_cSendBuff[4096];//     
	char  m_cReceiveBuff[1024];
	char* m_pcFileBuff;//      
	sMailInfo m_sMailInfo;
};
モジュール実装ファイル
/************************************************************************
*       
*         (          )
*Date:2011-12-01
************************************************************************/
#include "StdAfx.h"
#include "SendMail.h"
#include <atlenc.h>
#include "winsock2.h"
#pragma comment(lib,"WSOCK32")

CSendMail::CSendMail(void)
{
	m_pcFileBuff=NULL;
	memset(m_cSendBuff,0,sizeof(m_cSendBuff));
	memset(m_cReceiveBuff,0,sizeof(m_cReceiveBuff));
}


CSendMail::~CSendMail(void)
{
	DeleteAllPath();
}


void CSendMail::Char2Base64(char* pBuff64,char* pSrcBuff,int iLen)
{
	//1   1   1   1   1   1   1   1
	//    pBuff64  ↑    pBuff64+1
	//		   point     
	static char Base64Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//base64       
	int point;//           ,  2,4,6;   2
	point=2;
	int i;
	int iIndex;//base64     
	char n=0;//          
	for(i=0;i<iLen;i++)
	{
		if(point==2)
		{
			iIndex=((*pSrcBuff)>>point)&0x3f;//  pSrcBuff  point 
		}
		else if (point==4)
		{
			iIndex=((*pSrcBuff)>>point)&0xf;//  pSrcBuff  point 
		}
		else if(point==6)
		{
			iIndex=((*pSrcBuff)>>point)&0x3;//  pSrcBuff  point 
		}
		iIndex+=n;// pSrcBuff-1  point    Base64   
		*pBuff64++=Base64Encode[iIndex];//      pBuff64
		n=((*pSrcBuff)<<(6-point));//          
		n=n&0x3f;//  n      0
		point+=2;//          2
		if(point==8)//       8  pSrcBuff 6   ,         Base64  ,         
		{
			iIndex=(*pSrcBuff)&0x3f;//   6 ,      
			*pBuff64++=Base64Encode[iIndex];//
			n=0;//    0
			point=2;//      2
		}
		pSrcBuff++;

	}
	if(n!=0)
	{
		*pBuff64++=Base64Encode[n];
	}
	if(iLen%3==2)//          3     '='  
	{
		*pBuff64='=';
	}
	else if(iLen%3==1)
	{
		*pBuff64++='=';
		*pBuff64='=';
	}
}

void CSendMail::AddFilePath(char * pcFilePath)//      
{
	if(pcFilePath==NULL)
	{
		return;
	}
	int i;
	char* temp;
	for(i=0;i<m_pcFilePathList.GetCount();i++)
	{
		temp=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));
		if(strcmp(pcFilePath,temp)==0)//             
		{
			return;
		}
	}
	m_pcFilePathList.AddTail(pcFilePath);
}

void CSendMail::DeleteFilePath(char* pcFilePath)//      
{
	int i;
	char* temp;
	for(i=0;i<m_pcFilePathList.GetCount();i++)
	{
		temp=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));
		if(strcmp(temp,pcFilePath)==0)//      ,        
		{
			m_pcFilePathList.RemoveAt(m_pcFilePathList.FindIndex(i));
			delete[] temp;
			return;
		}
	}
}


void CSendMail::DeleteAllPath(void)
{
	m_pcFilePathList.RemoveAll();
}

int CSendMail::GetFileData(char* FilePath)
{
	m_pcFileBuff=NULL;
	if(FilePath==NULL)
	{
		return 0;
	}
	CFile f;
	int len;
	
	
	//USES_CONVERSION;
	CFileException e;
	if(!f.Open(/*A2W*/(FilePath),CFile::modeRead|CFile::modeNoTruncate|CFile::typeBinary, &e))
	{
		return 0;
	}
	len=(int)f.GetLength();
	m_pcFileBuff=new char[len+1];
	memset(m_pcFileBuff,0,len+1);
	f.Read(m_pcFileBuff,len);

	f.Close();
	return len;
}

void CSendMail::GetFileName(char* fileName,char* filePath)
{
	if(filePath==NULL || fileName==NULL)
	{
		return;
	}
	int i;
	for(i=0;i<(int)strlen(filePath);i++)
	{
		if(filePath[strlen(filePath)-1-i]=='\\')
		{
			memcpy(fileName,&filePath[strlen(filePath)-i],i);
			return;
		}
	}
}

bool CSendMail::CReateSocket(SOCKET &sock)
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD( 2, 2 );
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) 
	{
		return false;
	}
	if ( LOBYTE( wsaData.wVersion ) != 2 ||
		HIBYTE( wsaData.wVersion ) != 2 )
	{
		WSACleanup( );
		return false; 
	}
	sock = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
	if (sock == INVALID_SOCKET)
	{
		return false;
	}

	sockaddr_in servaddr;
	memset(&servaddr,0,sizeof(sockaddr_in));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(25);//       25  
	if(m_sMailInfo.m_pcIPName=="")
	{
		servaddr.sin_addr.s_addr = inet_addr(m_sMailInfo.m_pcIPAddr);//    IP  
	}
	else
	{
		struct hostent *hp=gethostbyname(m_sMailInfo.m_pcIPName);//    
		servaddr.sin_addr.s_addr=*(int*)(*hp->h_addr_list);
		char* ip = inet_ntoa(servaddr.sin_addr);
		strcpy(m_sMailInfo.m_pcIPAddr, ip);
	}


	int ret = connect(sock,(sockaddr*)&servaddr,sizeof(servaddr));//    
	if (ret == SOCKET_ERROR)
	{
		return false;
	}

	return true;
}


bool CSendMail::Logon(SOCKET &sock)
{
	recv(sock,m_cReceiveBuff,1024,0);

	memset(m_cSendBuff,0,sizeof(m_cSendBuff));
	sprintf_s(m_cSendBuff,"HELO %s\r
", m_sMailInfo.m_pcIPAddr); send(sock,m_cSendBuff,strlen(m_cSendBuff),0);// memset(m_cReceiveBuff, 0, sizeof(m_cReceiveBuff)); recv(sock,m_cReceiveBuff,1024,0); if(m_cReceiveBuff[0]!='2' || m_cReceiveBuff[1]!='5' || m_cReceiveBuff[2]!='0') { return false; } memset(m_cSendBuff,0,sizeof(m_cSendBuff)); sprintf_s(m_cSendBuff,"AUTH LOGIN\r
"); send(sock,m_cSendBuff,strlen(m_cSendBuff),0);// recv(sock,m_cReceiveBuff,1024,0); if(m_cReceiveBuff[0]!='3' || m_cReceiveBuff[1]!='3' || m_cReceiveBuff[2]!='4') { return false; } memset(m_cSendBuff,0,sizeof(m_cSendBuff)); Char2Base64(m_cSendBuff,m_sMailInfo.m_pcUserName,strlen(m_sMailInfo.m_pcUserName)); m_cSendBuff[strlen(m_cSendBuff)]='\r'; m_cSendBuff[strlen(m_cSendBuff)]='
'; send(sock,m_cSendBuff,strlen(m_cSendBuff),0);// recv(sock,m_cReceiveBuff,1024,0); if(m_cReceiveBuff[0]!='3' || m_cReceiveBuff[1]!='3' || m_cReceiveBuff[2]!='4') { return false; } memset(m_cSendBuff,0,sizeof(m_cSendBuff)); Char2Base64(m_cSendBuff,m_sMailInfo.m_pcUserPassWord,strlen(m_sMailInfo.m_pcUserPassWord)); m_cSendBuff[strlen(m_cSendBuff)]='\r'; m_cSendBuff[strlen(m_cSendBuff)]='
'; send(sock,m_cSendBuff,strlen(m_cSendBuff),0);// recv(sock,m_cReceiveBuff,1024,0); if(m_cReceiveBuff[0]!='2' || m_cReceiveBuff[1]!='3' || m_cReceiveBuff[2]!='5') { return false; } return true;// } bool CSendMail::SendHead(SOCKET &sock) { int rt; memset(m_cSendBuff,0,sizeof(m_cSendBuff)); sprintf_s(m_cSendBuff,"MAIL FROM:<%s>\r
",m_sMailInfo.m_pcSender); rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0); if(rt!=strlen(m_cSendBuff)) { return false; } recv(sock,m_cReceiveBuff,1024,0); memset(m_cSendBuff,0,sizeof(m_cSendBuff)); sprintf_s(m_cSendBuff,"RCPT TO:<%s>\r
",m_sMailInfo.m_pcReceiver); rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0); if(rt!=strlen(m_cSendBuff)) { return false; } recv(sock,m_cReceiveBuff,1024,0); memset(m_cSendBuff,0,sizeof(m_cSendBuff)); memcpy(m_cSendBuff,"DATA\r
",strlen("DATA\r
")); rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0); if(rt!=strlen(m_cSendBuff)) { return false; } recv(sock,m_cReceiveBuff,1024,0); memset(m_cSendBuff,0,sizeof(m_cSendBuff)); sprintf_s(m_cSendBuff,"From:\"%s\"<%s>\r
",m_sMailInfo.m_pcSenderName,m_sMailInfo.m_pcSender); sprintf_s(&m_cSendBuff[strlen(m_cSendBuff)],150,"To:\"INVT.COM.CN\"<%s>\r
",m_sMailInfo.m_pcReceiver); sprintf_s(&m_cSendBuff[strlen(m_cSendBuff)],150,"Subject:%s\r
Mime-Version: 1.0\r
Content-Type: multipart/mixed; boundary=\"INVT\"\r
\r
",m_sMailInfo.m_pcTitle); rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0); if(rt!=strlen(m_cSendBuff)) { return false; } return true; } bool CSendMail::SendTextBody(SOCKET &sock) { int rt; memset(m_cSendBuff,0,sizeof(m_cSendBuff)); sprintf_s(m_cSendBuff,"--INVT\r
Content-Type: text/plain;\r
charset=\"gb2312\"\r
\r
%s\r
\r
",m_sMailInfo.m_pcBody); rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0); if(rt!=strlen(m_cSendBuff)) { return false; } else { return true; } } bool CSendMail::SendFileBody(SOCKET &sock) { int i; char* filePath; int rt; int len; char fileName[128]; int pt=0; int nDestLen = 0; for(i=0;i<m_pcFilePathList.GetCount();i++) { pt=0; memset(fileName,0,128); filePath=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i)); len=GetFileData(filePath); GetFileName(fileName,filePath); sprintf_s(m_cSendBuff,"--INVT\r
Content-Type: application/octet-stream;\r
name=\"%s\"\r
Content-Transfer-Encoding: base64\r
Content-Disposition: attachment;\r
filename=\"%s\"\r
\r
",fileName,fileName); send(sock,m_cSendBuff,strlen(m_cSendBuff),0); while (pt<len) { memset(m_cSendBuff,0,sizeof(m_cSendBuff)); //760 1024 ,(760/4)*3=570 nDestLen = 4096; Base64Encode((BYTE*)m_pcFileBuff+pt, min(len-pt,570), m_cSendBuff, &nDestLen); int len1 = strlen(m_cSendBuff); pt+=min(len-pt,570); if(pt==len) { m_cSendBuff[len1] = '\r'; m_cSendBuff[len1+1] = '
'; m_cSendBuff[len1+2] = '\0'; } else m_cSendBuff[len1] = '\0'; rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0); if(rt!=strlen(m_cSendBuff)) { return false; } } if(len!=0) { delete [] m_pcFileBuff; } } return true; } bool CSendMail::SendEnd(SOCKET &sock) { sprintf_s(m_cSendBuff,"--INVT--\r
.\r
"); send(sock,m_cSendBuff,strlen(m_cSendBuff),0); sprintf_s(m_cSendBuff,"QUIT\r
"); send(sock,m_cSendBuff,strlen(m_cSendBuff),0); closesocket(sock); WSACleanup(); return true; } bool CSendMail::SendMail(sMailInfo &smailInfo) { memcpy(&m_sMailInfo,&smailInfo,sizeof(smailInfo)); if(m_sMailInfo.m_pcBody==NULL || m_sMailInfo.m_pcIPAddr==NULL || m_sMailInfo.m_pcIPName==NULL || m_sMailInfo.m_pcReceiver==NULL || m_sMailInfo.m_pcSender==NULL || m_sMailInfo.m_pcSenderName==NULL || m_sMailInfo.m_pcTitle==NULL || m_sMailInfo.m_pcUserName==NULL || m_sMailInfo.m_pcUserPassWord==NULL) { return false; } SOCKET sock; if(!CReateSocket(sock))// { return false; } if(!Logon(sock))// { return false; } if(!SendHead(sock))// { return false; } if(!SendTextBody(sock))// { return false; } if(!SendFileBody(sock))// { return false; } if(!SendEnd(sock))// , sock { return false; } return true; }

よびだし
void Ctest05303Dlg::OnBnClickedOk()
{
	// TODO:               
	//OnOK();
	CSendMail mail;
	sMailInfo info;

	memcpy(info.m_pcIPAddr, "123.125.50.138", strlen("123.125.50.138"));
	info.m_pcIPName = "smtp.163.com";
	info.m_pcReceiver = "[email protected]";
	info.m_pcSender = "   @163.com";
	info.m_pcUserName = "   ";
	info.m_pcUserPassWord = "  ";

	info.m_pcSenderName = "     ";
	info.m_pcTitle = "  ";
	info.m_pcBody = "  ";
	mail.AddFilePath("e:\\3.zip");
	mail.SendMail(info);
}

変換元:http://blog.csdn.net/ybjx111/article/details/7031055
PS:原文はqqメールボックスに添付ファイルを送信して問題があって、ここのbase 64コードは原文と異なっています