⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.cpp

📁 smtp c语言下的实现 smtp c语言下的实现smtp c语言下的实现
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	if(cc.size())
		buffer="Cc: ";
	for(i=0;i<cc.size();i++)
	{
		if(i!=0)
			buffer+=",";
		HeadTextTemple("Cc", cc[i] , str, FALSE);
		buffer+=str;
	}
	if(cc.size())
		buffer+="\r\n";
}
void Bcc(const vector<string >& bcc,string & buffer)
{
	string str;
	int i;
	buffer="";
	if(bcc.size())
		buffer="Bcc: ";
	for(i=0;i<bcc.size();i++)
	{
		if(i!=0)
			buffer+=",";
		HeadTextTemple("Bcc", bcc[i] , str, FALSE);
		buffer+=str;
	}
	if(bcc.size())
		buffer+="\r\n";
}

void ReplyTo(const string& addr,string & buffer)
{
	HeadTextTemple("Reply-to", addr , buffer);
}
void XMailer(string & buffer)
{
	char str[BUFFER_BLOCK_SIZE];
	EncodingBase64("自己的Mailer",str);
	buffer=string("X-mailer: =?GB2312?B?") + str +"?=\r\n";
}
void MessageID(const string& from,string & buffer)
{
	string::size_type pos=0;
	char tB[BUFFER_BLOCK_SIZE];
	string str;
	long t=time(NULL);
	if((pos=from.find('@',pos))!=string::npos)
	{
		str=from.c_str()+pos;
		if((pos=str.find('>',pos))!=string::npos)
			sprintf(tB,"Message-ID: %d%s\r\n",t,str.c_str());
		else
			sprintf(tB,"Message-ID: <%d%s>\r\n",t,str.c_str());
		buffer=tB;
	}
	else
	{
		buffer=string("Message-ID: ")+ltoa(t,tB,10) +"\r\n";
	}
}

void DataHead(const string& from,
			  const vector<string >& to,
			  const vector<string >& cc,
			  const vector<string >& bcc,
			  const string & subject,
			  const string& bodytext,
	    	  const string& bodytexthtml,
			  BOOL bHtml,
			  BOOL bAttachment,
			  string& majorSplitTag,
			  string& buffer)
{
	string str;
	majorSplitTag="====MajorSplitTag====";
	buffer="";

	Date(str);
	buffer+=str;
	From(from,str);
	buffer+=str;
	To(to,str);
	buffer+=str;
	Cc(cc,str);
	buffer+=str;
	Bcc(bcc,str);
	buffer+=str;
	Subject(subject,str);
	buffer+=str;
	MessageID(from,str);
	buffer+=str;
	XMailer(str);
	buffer+=str;
	buffer+="Mime-Version: 1.0\r\n";
	if(!bHtml && !bAttachment) //pure text and no attachment
	{
		buffer+="Content-Type: text/plain;\r\n\tcharset=\"gb2312\"\r\n";
		buffer+="Content-Transfer-Encoding: base64\r\n";
	}
	else if(!bHtml) //having attachment
	{
		buffer+="Content-Type: multipart/mixed;\r\n\tboundary=\""+majorSplitTag+"\"\r\n";
	}
	else if(!bAttachment) //html
	{
		buffer+="Content-Type: multipart/alternative;\r\n\tboundary=\""+majorSplitTag+"\"\r\n";
	}
	else	//html and attachment
	{
		buffer+="Content-Type: multipart/mixed;\r\n\tboundary=\""+majorSplitTag+"\"\r\n";
	}
	majorSplitTag="--"+majorSplitTag+"\r\n";
}

void DataBody_PureText(const string& bodytext_base64, string& buffer)
{
	buffer=bodytext_base64;
	buffer+="\r\n";
}

void DataBody_HtmlOnly(const string& bodytext_base64, 
					   const string& html_base64,
					   const string& majorSplitTag,
					   string& buffer)
{
	buffer="This is a multi-part message in MIME format.\r\n";
	buffer+="\r\n";
	buffer+=majorSplitTag;
	buffer+="Content-Type: text/plain;\r\n\tcharset=\"gb2312\"\r\n";
	buffer+="Content-Transfer-Encoding: base64\r\n";
	buffer+="\r\n";
	buffer+=bodytext_base64;
	buffer+="\r\n";
	buffer+=majorSplitTag;
	buffer+="Content-Type: text/html;\r\n\tcharset=\"gb2312\"\r\n";
	buffer+="Content-Transfer-Encoding: base64\r\n";
	buffer+="\r\n";
	buffer+=html_base64;
	buffer+="\r\n";
	buffer+=majorSplitTag;
}

void DataBody_TextAndAttachments(const string& bodytext_base64, 
								 const vector<string >& attachments,
								   const string& majorSplitTag,
								   string& buffer)
{
	int i;
	string str;
	char sDrive[_MAX_DRIVE];	char sDir[_MAX_DIR];
	char sFname[_MAX_FNAME];	char sExt[_MAX_EXT];
	char strBuffer[BUFFER_BLOCK_SIZE];

	buffer="This is a multi-part message in MIME format.\r\n";
	buffer+="\r\n";
	buffer+=majorSplitTag;
	buffer+="Content-Type: text/plain;\r\n\tcharset=\"gb2312\"\r\n";
	buffer+="Content-Transfer-Encoding: base64\r\n";
	buffer+="\r\n";
	buffer+=bodytext_base64;
	buffer+="\r\n";

	for(i=0; i<attachments.size() ;i++)
	{
		_splitpath(attachments[i].c_str(), sDrive, sDir, sFname, sExt);
		strcat(sFname,sExt);
		EncodingBase64(sFname,strBuffer);
		str=string("=?gb2312?B?") + strBuffer + "?=";

		buffer+=majorSplitTag;
		buffer+=string("Content-Type: application/octet-stream;\r\n\tname=\"") + str + "\"\r\n";
		buffer+="Content-Transfer-Encoding: base64\r\n";
		buffer+="Content-Disposition: attachment;\r\n\t";
		buffer+=string("filename=\"")+str+"\"\r\n";
		buffer+="\r\n";
		EncodeFileBase64(attachments[i],str);
		buffer+=str+"\r\n";
	}
	buffer+=majorSplitTag;
}


void DataBody_HtmlAndAttachments(const string& bodytext_base64, 
								 const string& html_base64, 
								 const vector<string >& attachments,
								 const string& majorSplitTag,
								 const string& subSplitTag,
								 string& buffer)
{
	int i;
	string str,sub;
	char sDrive[_MAX_DRIVE];	char sDir[_MAX_DIR];
	char sFname[_MAX_FNAME];	char sExt[_MAX_EXT];
	char strBuffer[BUFFER_BLOCK_SIZE];
	
	buffer="This is a multi-part message in MIME format.\r\n";
	buffer+="\r\n";
	buffer+=majorSplitTag;
	buffer+="Content-Type: multipart/alternative;\r\n\tboundary=\"" + subSplitTag + "\"\r\n";
	buffer+="\r\n";
	sub="--"+subSplitTag+"\r\n";

	buffer+=sub;
	buffer+="Content-Type: text/plain;\r\n\tcharset=\"gb2312\"\r\n";
	buffer+="Content-Transfer-Encoding: base64\r\n";
	buffer+="\r\n";
	buffer+=bodytext_base64;
	buffer+="\r\n";	
	
	buffer+=sub;
	buffer+="Content-Type: text/html;\r\n\tcharset=\"gb2312\"\r\n";
	buffer+="Content-Transfer-Encoding: base64\r\n";
	buffer+="\r\n";
	buffer+=html_base64;
	buffer+="\r\n";

	buffer+=sub;

	for(i=0; i<attachments.size() ;i++)
	{
		_splitpath(attachments[i].c_str(), sDrive, sDir, sFname, sExt);
		strcat(sFname,sExt);
		EncodingBase64(sFname,strBuffer);
		str=string("=?gb2312?B?") + strBuffer + "?=";

		buffer+=majorSplitTag;
		buffer+=string("Content-Type: application/octet-stream;\r\n\tname=\"") + str + "\"\r\n";
		buffer+="Content-Transfer-Encoding: base64\r\n";
		buffer+="Content-Disposition: attachment;\r\n\t";
		buffer+=string("filename=\"")+str+"\"\r\n";
		buffer+="\r\n";
		EncodeFileBase64(attachments[i],str);
		buffer+=str+"\r\n";
	}

	buffer+=majorSplitTag;
}


void DataBody(	BOOL bHtmlBody,
				BOOL bAttachment,
				const string& majorSplitTag,
				const string& bodytext,
				const string& bodytexthtml,
				const vector<string> & attachments,
				string& buffer)
{
	string subSplitTag;
	string attachStr;
	string bodytext_base64,bodyhtml_base64;

	int length;
	char *tBuffer;

	subSplitTag="====SubSplitTag====";

	//text base64 encode
	length=(bodytext.length()/3+1)*4;
	tBuffer= new char[length+1];
	EncodingBase64(bodytext.c_str(),tBuffer);
	bodytext_base64=tBuffer;
	delete[] tBuffer;

	//html base64 encode if it's html coded email
	if(bHtmlBody)
	{
		length=(bodytexthtml.length()/3+1)*4;
		tBuffer= new char[length+1];
		EncodingBase64Adv(bodytexthtml.c_str(), bodytexthtml.length(), tBuffer);
		bodyhtml_base64=tBuffer;
		delete[] tBuffer;
	}
	
	if(!bHtmlBody && !bAttachment)	//pure text
	{
		DataBody_PureText(bodytext_base64,buffer);
	}
	else if(!bHtmlBody)				//text and attachments
	{
		DataBody_TextAndAttachments(bodytext_base64,attachments,majorSplitTag,buffer);
	}
	else if(!bAttachment)			//text,html 
	{
		DataBody_HtmlOnly(bodytext_base64,bodyhtml_base64,majorSplitTag,buffer);
	}
	else							//text, html and attachments
	{
		DataBody_HtmlAndAttachments(bodytext_base64,bodyhtml_base64,attachments,majorSplitTag,subSplitTag,buffer);
	}
	buffer+="\r\n.\r\n";
}

BOOL EncodeFileBase64(const string& filename, string& code)
{
	ifstream file;
	filebuf *fB;
	int length;
	char buffer[3073],des[4097];
	int curLen;

	code="";

	file.open(filename.c_str(),ios::binary);
	if(file.fail())
		return FALSE;

	//get the file length
	fB=file.rdbuf();
	length=fB->pubseekoff(0,ios::end,ios::in) - fB->pubseekoff(0,ios::beg,ios::in);
	//send filelength
	fB->pubseekoff(0,ios::beg,ios::in); //file pointer location
	while(length>0)
	{
		if(length<3072)
			curLen=length;
		else
			curLen=3072;
		file.read(buffer,curLen);
//		buffer[curLen]='\0';
		EncodingBase64Adv(buffer, curLen, des);
		code+=des;
		length-=3072;
	}
	file.close();
	return TRUE;
}

BOOL ReadFileToStr(const string& filename, string& code)
{
	ifstream file;
	filebuf *fB;
	int length;
	char buffer[BUFFER_BLOCK_SIZE+1];
	int curLen;
	code="";

	file.open(filename.c_str(),ios::binary);
	if(file.fail())
		return FALSE;

	//get the file length
	fB=file.rdbuf();
	length=fB->pubseekoff(0,ios::end,ios::in) - fB->pubseekoff(0,ios::beg,ios::in);
	//send filelength
	fB->pubseekoff(0,ios::beg,ios::in); //file pointer location
	while(length>0)
	{
		if(length<BUFFER_BLOCK_SIZE)
			curLen=length;
		else
			curLen=BUFFER_BLOCK_SIZE;
		file.read(buffer,curLen);
		buffer[curLen]='\0';
		code+=buffer;
		length-=BUFFER_BLOCK_SIZE;
	}
	file.close();
	return TRUE;
}


/**********************************************************************************/
u_long ConvertHostnameToLongHostAddress(const char * destAddress)
{
	hostent * host=gethostbyname((const char *)destAddress);
	if(host==NULL)
	{
		cout<<"Cann't resolve this host name: "<<GetLastError()<<endl;
		return -1;
	}
	return ntohl((*(struct in_addr*)host->h_addr).S_un.S_addr);
}

int Socks5StartIPv4(const string& proxyServerHostName,
				u_int proxyServerPort,
				const string& username, 
				const string& pass,
				u_long destAddress,
				u_int destPort,
				SOCKET& sock)
{
	sockaddr_in serverAddr;
	int retCode;
	char buffer[BUFFER_BLOCK_SIZE];
	BYTE version=5;
	BYTE authorWay1=0;	//no authority
	BYTE authorWay2=2;	//user/pass authority
	int rsv=0;
	string addrStr;
	u_int t;
	
	sock=socket(AF_INET, SOCK_STREAM,0);
	serverAddr.sin_addr.S_un.S_addr=htonl(ConvertHostnameToLongHostAddress(proxyServerHostName.c_str()));
	serverAddr.sin_family=AF_INET;
	serverAddr.sin_port=htons(proxyServerPort);
	cout<<"Connecting to "<<inet_ntoa(serverAddr.sin_addr)<<"\tPort:"<<proxyServerPort<<endl;
	cout.flush();
	if(connect(sock,(const sockaddr*)&serverAddr,sizeof(sockaddr))==SOCKET_ERROR)
	{
		cout<<"Cannot connect to Server: "<<proxyServerHostName.c_str()<<endl;
		cout.flush();
		closesocket(sock);
		return -1;
	}

	//1. authoutication negotiation
	sprintf(buffer,"%c%c%c%c",version,2,authorWay1,authorWay2);
	send(sock,buffer,4,0);
	retCode=recv(sock,buffer,BUFFER_BLOCK_SIZE,0);
	DEAL_SOCK_ERROR(retCode,sock);
	if(char(retCode)==0xFF)
		return 1;
	buffer[retCode]='\0';
	cout<<buffer;

	//user/pass authentication
	if(buffer[1]==authorWay2)
	{
		//user name
		sprintf(buffer,"%c%c%s%c%s",char(0x01),char(username.length()),username.c_str(),
				char(pass.length()),pass.c_str());
		t=3+username.length()+pass.length();
		send(sock, buffer, t, 0);
		retCode=recv(sock,buffer,BUFFER_BLOCK_SIZE,0);
		DEAL_SOCK_ERROR(retCode,sock);
		if(char(retCode)==0xFF)
			return 1;
		buffer[retCode]='\0';
		if(buffer[1]!=0)
			return 1;
	}
	
	//1. authoutication negotiation
	addrStr=buffer;
	t=htons(destPort);
	sprintf(buffer,"%c%c%c%c%c%c%c%c%c%c",version,char(0x01),rsv,char(0x01),
		((char*)&destAddress)[3],((char*)&destAddress)[2],((char*)&destAddress)[1],((char*)&destAddress)[0],
		((char *)&t)[0],((char *)&t)[1]);
	cout<<buffer;
	send(sock,buffer,10,0);
	retCode=recv(sock,buffer,BUFFER_BLOCK_SIZE,0);
	DEAL_SOCK_ERROR(retCode,sock);
	buffer[retCode]='\0';
	if(buffer[1]!=0)
	{
		sprintf(buffer,"%x",buffer[1]);
		cout<<"Failure in negotiation: "<<buffer<<endl;
		return 1;
	}
	return 0;
}

BOOL SendMessage(SOCKET sock, const char* buffer, int bufferLen)
{
	int startPos;
	int ret;
	startPos=0;
	while(bufferLen>0)
	{
		ret=send(sock,buffer+startPos,bufferLen,0);
		if(ret==0)
			break;
		if(ret==SOCKET_ERROR)
			return FALSE;
		startPos+=ret;
		bufferLen-=ret;
	}
	return bufferLen==0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -