VC++编的电子邮件发送和接收程序,要实验报告。急,急,急!_

VC++编的电子邮件发送和接收程序,要实验报告。急,急,急!_,第1张

电子邮件服务作为Internet上应用最多和最广的服务项目得到了非常广泛的应用,在网络应用中也起到非常重要的作用。如同其他的网络服务,电子邮件系统也有其使用的传输协议,包括SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)、POP(Post Office Protocol,邮局协议)和IMAP(Internet Message Access Protocal,消息访问咐培仿协议)等,这些协议应用于电子邮件的发送和接收。一些邮件处理软件如OutLook Express和FoxMail等就是按照SMTP和POP3 协议结合Windows Sockets套接字进行设计来收发邮件的。本文以SMTP协议为研究对象,在Visual C++ 6.0编程环境下按照SMTP协议通过套接字发送SMTP命令,接收并处理邮件服务器的反馈信息,从而实现对电子邮件的发送。

SMTP协议的通讯模型和会话流程

SMTP协议通讯模型

SMTP协议是TCP/IP协议族中的一员,主要对如何将电子邮件从发送方地址传送到接收方地址,也即是对传输的规则做了规定。SMTP协议的中漏通信模型并不复杂,主要工作集中在发送SMTP和接收SMTP上:首先针对衡纤用户发出的邮件请求,由发送SMTP建立一条连接到接收SMTP的双工通讯链路,这里的接收SMTP是相对于发送SMTP而言的,实际上它既可以是最终的接收者也可以是中间传送者。发送SMTP负责向接收SMTP发送SMTP命令,而接收SMTP则负责接收并反馈应答。

只能说主要代码,程序是一个整体,如果友凯竖要直接编译通过,那就要整个发了

你自己改下吧

int CMail::sendmail()

{

int crecv

if(smtplogin()==0)

{

return 0

}

//发送mail from 返回250

sprintf(m_sendbuff,"%s%s%s","mail from:<",m_user,"@163.com>\r\n")

if(senddata()==0)

{

return 0

}

if(recvdata()==0)

{

return 0

}

if(strncmp(m_recvbuff,"250",3)!=NULL)

{

m_error=MAIL_FROM_ERROR

return 0

}

//发送rcpt to 返回250

sprintf(m_sendbuff,"%s%s%s","rcpt to:<",m_rcptto,">\r\n")

if(senddata()==0)

{

return 0

}

if(recvdata()==0)

{

return 0

}

if(strncmp(m_recvbuff,"250",3)!=NULL)

{

m_error=RCPT_TO_ERROR

return 0

}

//发送data\r\n 返回354

sprintf(m_sendbuff,"%s","data\r\n")

if(senddata()==0)

{

return 0

}

if(recvdata()==0)

{

return 0

}

if(strncmp(m_recvbuff,"354",3)!=NULL)

{

m_error=DATA_ERROR

return 0

}

//信好大头

if(!SetMailHeader(m_sendbuff))

{

m_error=MAILHEADER_ERROR

return 0

}

if(senddata()==0)

{

return 0

}

//发送空行

sprintf(m_sendbuff,"%s","\r\n\r\n")

if(senddata()==0)

{

return 0

}

/孙衫/发送邮件body

sprintf(m_sendbuff,"%s%s",m_data,"\r\n")

if(senddata()==0)

{

return 0

}

if(m_attachment!=NULL)

{

char **pp

for(pp=m_attachment*pp!=0pp++)

{

FILE* fp

char *buf

//准备发送附件,首先发送分界线,必须!

sprintf(m_sendbuff,"%s%s%s","--",BOUNDARY_TEXT,"\r\n")

if(senddata()==0)

{

return 0

}

sprintf(m_sendbuff,"%s%s%s","Content-Type: application/x-msdownloadname=\"",strrchr(*pp,'\\')+1,"\"\r\n")

if(senddata()==0)

{

return 0

}

sprintf(m_sendbuff,"%s","Content-Transfer-Encoding: base64\r\n")

if(senddata()==0)

{

return 0

}

sprintf(m_sendbuff,"%s%s%s","Content-Disposition: attachmentfilename=\"",strrchr(*pp,'\\')+1,"\"\r\n\r\n")

if(senddata()==0)

{

return 0

}

//将文件base64编码后发送

fp=fopen(*pp,"rb")

if(fp==NULL)

{

m_error=OPEN_FILE_ERROR

return 0

}

buf=new char[BUFFERSIZE+1]

memset(buf,0,BUFFERSIZE+1)

int readcount=0

while(!feof(fp))

{

readcount=fread(buf,1,BUFFERSIZE,fp)

if(readcount>0)

{

*(buf+readcount)='\0'

sprintf(m_sendbuff,"%s%s",base64(buf,ENCODE,readcount),"\r\n")

if(senddata()==0)

{

return 0

}

memset(buf,0,BUFFERSIZE+1)

}

}

sprintf(m_sendbuff,"%s","\r\n")

if(senddata()==0)

{

return 0

}

delete[] buf

fclose(fp)

}

}

if(m_attachment!=NULL)

{

//附件发送完毕,发送分界线

sprintf(m_sendbuff,"%s%s%s","--",BOUNDARY_TEXT,"--\r\n")

if(senddata()==0)

{

return 0

}

}

//发送.\r\n 结束 返回250

sprintf(m_sendbuff,"%s",".\r\n")

if(senddata()==0)

{

return 0

}

crecv=recv(s,m_recvbuff,MAX_LENGTH,0)

if(strncmp(m_recvbuff,"250",3)!=NULL)

{

m_error=END_DATA_ERROR

return 0

}

else

{

showmessage(NULL,"邮件发送成功","",NULL)

}

//退出

sprintf(m_sendbuff,"%s","quit\r\n")

if(senddata()==0)

{

return 0

}

if(closesocket(s)!=0)

{

m_error=CLOSE_SOCKET_ERROR

return 0

}

if(WSACleanup()!=0)

{

m_error=CLEANUP_WSA_ERROR

return 0

}

return 1

}

int CMail::senddata()

{

int idx = 0

int csend

int count=strlen(m_sendbuff)

while(count>0)

{

if((csend=send(s,m_sendbuff+idx,count,0))==SOCKET_ERROR)

{

m_error =WSA_SEND_ERROR

return 0

}

if(csend==0)

{

break

}

count-=csend

idx+=csend

}

return 1

}

int CMail::recvdata()

{

int crecv

crecv=recv(s,m_recvbuff,MAX_LENGTH,0)

if(crecv==SOCKET_ERROR)

{

m_error =WSA_RECV_ERROR

return 0

}

else if(crecv==0)

{

m_error=WSA_RECV_ERROR

return 0

}

else

{

}

return 1

}

int CMail::chartoindex(char c)

{

if(c>=65&&c<=90)

{

c-=65

}

else if(c>=97&&c<=122)

{

c-=71

}

else if(c>=48&&c<=57)

{

c+=4

}

else if(c==43)//'+'

{

c=62

}

else if(c==47)//'/'

{

c=63

}

else if(c==61)//'='

{

c=0

}

else

{

m_error=DECODE_ERROR

return 0

}

return c

}

bool CMail::SetMailHeader(char* header)

{

// "Date:","From:","To:",

// "Message-ID:","Subject:","MIME-Version:",

// "Content-Type:","X-Priority:",

// "X-Mailer:","X-CM-TRANSID:","X-CM-SenderInfo:",

// "X-Coremail-Antispam:","\r\n\r\n"

TCHAR szDate[500]

TCHAR sztTime[500]

// Date: <SP><dd><SP><mon><SP><yy><SP><hh>":" <mm>":" <ss><SP><zone><CRLF>

SYSTEMTIME st={0}

::GetSystemTime(&st)

::GetDateFormat(MAKELCID(0x0409,SORT_DEFAULT),0,&st,"ddd\',\' dd MMM yyyy",szDate,sizeof(szDate))

::GetTimeFormat(MAKELCID(0x0409,SORT_DEFAULT),TIME_FORCE24HOURFORMAT,&st,"HH\':\'mm\':\'ss",sztTime,sizeof(sztTime))

sprintf(header,"Date: %s %s\r\n", szDate, sztTime)

// From: <SP><sender> <SP>"<" <sender-email>">" <CRLF>

if(m_mailfrom!=NULL)

{

strcat(header,"From: ")

strcat(header," <")

strcat(header,m_mailfrom)

strcat(header, ">\r\n")

}

// X-Mailer: <SP><xmailer-app><CRLF>

if(m_xmailer!= NULL)

{

strcat(header,"X-Mailer: ")

strcat(header, m_xmailer)

strcat(header, "\r\n")

}

// X-Priority: <SP><number><CRLF>

switch(m_priority)

{

case XPRIORITY_HIGH:

strcat(header,"X-Priority: 2 (High)\r\n")

break

case XPRIORITY_NORMAL:

strcat(header,"X-Priority: 3 (Normal)\r\n")

break

case XPRIORITY_LOW:

strcat(header,"X-Priority: 4 (Low)\r\n")

break

default:

strcat(header,"X-Priority: 3 (Normal)\r\n")

}

// To: <SP><remote-user-mail><CRLF>

if(m_rcptto!=NULL)

{

strcat(header,"To: ")

strcat(header, m_rcptto)

strcat(header, "\r\n")

}

// Subject: <SP><subject-text><CRLF>

if(m_subject!=NULL)

{

strcat(header, "Subject: ")

strcat(header, m_subject)

strcat(header, "\r\n")

}

// MIME-Version: <SP>1.0 <CRLF>

strcat(header,"MIME-Version: 1.0\r\n")

//attachment

if(m_attachment==NULL)

{ //如果没附件

strcat(header,"Content-type: text/plaincharset=GB2312\r\n")

strcat(header,"Content-Transfer-Encoding: 7bit\r\n")

strcat(header,"\r\n")

}

else

{ //如果有附件,设置分界线,每个子段以--BOUNDARY_TEXT行开始,父段则以--BOUNDARY_TEXT--行结束,不同段之间用空行分隔

strcat(header,"Content-Type: multipart/mixedboundary=\"")

strcat(header,BOUNDARY_TEXT)

strcat(header,"\"\r\n")

strcat(header,"\r\n")//这个空行不能少

//第一部分为文本内容

strcat(header,"--")strcat(header,BOUNDARY_TEXT)strcat(header,"\r\n")//加上分界线

//以下跟没附件时的一样

strcat(header,"Content-type: text/plaincharset=GB2312\r\n")//注意GB2312 否则会出现中文乱码

strcat(header,"Content-Transfer-Encoding: 7bit\r\n")

}

// done

return true

}

int CMail::senddata()

{

int idx = 0

int csend

int count=strlen(m_sendbuff)

while(count>0)

{

if((csend=send(s,m_sendbuff+idx,count,0))==SOCKET_ERROR)

{

m_error =WSA_SEND_ERROR

return 0

}

if(csend==0)

{

break

}

count-=csend

idx+=csend

}

return 1

}

int CMail::recvdata()

{

int crecv

crecv=recv(s,m_recvbuff,MAX_LENGTH,0)

if(crecv==SOCKET_ERROR)

{

m_error =WSA_RECV_ERROR

return 0

}

else if(crecv==0)

{

m_error=WSA_RECV_ERROR

return 0

}

else

{

}

return 1

}

int CMail::smtplogin()

{

//调用成员函数connect

if(connect()==0)

{

return 0

}

if(recvdata()==0)

{

return 0

}

if(strstr(m_recvbuff,"220")==NULL)//220

{

m_error=UNKNOWEN_ERROR

return 0

}

//发送helo 返回250

sprintf(m_sendbuff,"%s","helo 543880135\r\n")

if(senddata()==0)

{

return 0

}

if(recvdata()==0)

{

return 0

}

if(strncmp(m_recvbuff,"250",3)!=NULL)

{

m_error=HELO_ERROR

return 0

}

//发送auth login 返回334

sprintf(m_sendbuff,"%s","auth login\r\n")

if(senddata()==0)

{

return 0

}

if(recvdata()==0)

{

return 0

}

if(strncmp(m_recvbuff,"334",3)!=NULL)

{

m_error=AUTH_LOGIN_ERROR

return 0

}

//发送经过base64编码后的用户名,返回334

sprintf(m_sendbuff,"%s%s",base64(m_user,ENCODE,strlen(m_user)),"\r\n")

if(senddata()==0)

{

return 0

}

if(recvdata()==0)

{

return 0

}

if(strncmp(m_recvbuff,"334",3)!=NULL)

{

m_error=USER_ERROR

return 0

}

//发送经过base64编码后的密码 返回235

sprintf(m_sendbuff,"%s%s",base64(m_pass,ENCODE,strlen(m_pass)),"\r\n")

if(senddata()==0)

{

return 0

}

if(recvdata()==0)

{

return 0

}

if(strncmp(m_recvbuff,"235",3)!=NULL)

{

m_error=PASS_ERROR

return 0

}

return 1

}

int CMail::connect()

{

WSADATA wsadata

struct sockaddr_in sock_addr

HOSTENT *phostent

struct in_addr inaddr

if(WSAStartup(MAKEWORD(1,1),&wsadata)<0)

{

m_error=WSA_INIT_ERROR

return 0

}

/*---------------根据域名获取网络地址,存放在struct in_addr中----------------*/

phostent=gethostbyname(m_server)//pop.163.com

if(phostent!=NULL)

{

// lpAddr=phostent->h_addr_list[0]

memmove(&inaddr,phostent->h_addr_list[0],4)//220.181.12.101

}

else

{

m_error=CONNECTSERVER_ERROR

return 0

}

/*---------------根据域名获取网络地址,存放在struct in_addr中----------------*/

s=socket(AF_INET, SOCK_STREAM,IPPROTO_TCP)//SOCK_STREAM SOCK_DGRAM

sock_addr.sin_family=AF_INET

sock_addr.sin_port=htons(m_port)

sock_addr.sin_addr=inaddr//直接结构体赋值给结构体,或者写成:sock_addr.sin_addr.s_addr=inaddr.S_un.S_addr

if(::connect(s,(struct sockaddr *)&sock_addr,sizeof(sock_addr)))

{

m_error=CONNECT_ERROR

return 0

}

return 1

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12474112.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存