高三计算机课件 网络课程设计报告利用C实现SMTP协.docx
《高三计算机课件 网络课程设计报告利用C实现SMTP协.docx》由会员分享,可在线阅读,更多相关《高三计算机课件 网络课程设计报告利用C实现SMTP协.docx(70页珍藏版)》请在冰豆网上搜索。
高三计算机课件网络课程设计报告利用C实现SMTP协
利用C++实现SMTP协议
1.概述
SMTP(SimpleMailTransferProtocol)即简单邮件传输协议,是一种提供可靠且有效电子邮件传输的协议。
SMTP是建立在FTP文件传输服务上的一种邮件服务,主要用于传输系统之间的邮件信息并提供与来信有关的通知。
SMTP目前已是事实上的在Internet传输E-Mail的标准,是一个相对简单的基于文本的协议。
在其之上指定了一条消息的一个或多个接收者(在大多数情况下被确定是存在的),然后消息文本就传输了。
可以很简单地通过Telnet程序来测试一个SMTP服务器,SMTP使用TCP端口25。
要为一个给定的域名决定一个SMTP服务器,需要使用MX(MaileXchange)DNS。
。
1.1设计题目及实现目标
设计题目:
利用C++实现SMTP协议;
实现目标:
实现SMTP协议的基本功能,包括客户机的命令与数据。
1.2开发环境简介
本次开发用VisualC++6.0作为开发环境。
VC++是微软公司开发的一个IDE(集成开发环境),换句话说,就是使用c++的一个开发平台.有些软件就是这个编出来的...另外还有VB,VF.只是使用不同语言.但是,vc++是Windows平台上的C++编程环境,学习VC要了解很多Windows平台的特性并且还要掌握MFC、ATL、COM等的知识,难度比较大。
Windows下编程需要了解Windows的消息机制以及回调(callback)函数的原理;MFC是Win32API的包装类,需要理解文档视图类的结构,窗口类的结构,消息流向等等;COM是代码共享的二进制标准,需要掌握其基本原理等等。
VC作为一个主流的开发平台一直深受编程爱好者的喜爱,但是很多人却对它的入门感到难于上青天,究其原因主要是大家对他错误的认识造成的,严格的来说VC++不是门语言,虽然它和C++之间有密切的关系,如果形象点比喻的话,可以C++看作为一种”工业标准”,而VC++则是某种操作系统平台下的”厂商标准”,而”厂商标准”是在遵循”工业标准”的前提下扩展而来的。
VC++应用程序的开发主要有两种模式
2.系统设计分析
2.1协议分析
SMTP独立于特定的传输子系统,且只需要可靠有序的数据流信道支持。
SMTP重要特性之一是其能跨越网络传输邮件,即“SMTP邮件中继”。
通常,一个网络可以由公用互联网上TCP可相互访问的主机、防火墙分隔的TCP/IP网络上TCP可相互访问的主机,及其它LAN/WAN中的主机利用非TCP传输层协议组成。
使用SMTP,可实现相同网络上处理机之间的邮件传输,也可通过中继器或网关实现某处理机与其它网络之间的邮件传输。
SMTP协议工作原理
SMTP是工作在两种情况下:
一是电子邮件从客户机传输到服务器:
二是从某一个服务器传输到另一个服务器。
SMTP也是个请求/响应协议,命令和响应都是基于ASCⅡ文本,并以CR和LF符结束。
响应包括一个表示返回状态的三位数字代码。
SMTP在TCP协议25号端口监听连续请求。
连接和发送过程如下:
(1)建立TCP连接。
(2)客户端发送HELO命令以标识发件人自己的身份,然后客户端发送MAIL命令;服务器端正希望以OK作为响应,表明准备接收。
(3)客户端发送RCPT命令,以标识该电子邮件的计划接收人,可以有多个RCPT行;服务器端则表示是否愿意为收件人接收邮件。
(4)协商结束,发送邮件,用命令DATA发送。
(5)以“.”号表示结束输入内容一起发送出去,结束此次发送,用QUIT命令退出。
3.程序核心代码
3.1服务器端相关代码:
1)、相关核心代码如下:
//SMTPSeverDlg.cpp:
implementationfile
#include"stdafx.h"
#include"SMTPSever.h"
#include"SMTPSeverDlg.h"
#include"Picture.h"
#include
//CSMTPSeverDlgmessagehandlers
BOOLCSMTPSeverDlg:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
//Add"About..."menuitemtosystemmenu.
//IDM_ABOUTBOXmustbeinthesystemcommandrange.
ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!
=NULL)
{
CStringstrAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!
strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
//Settheiconforthisdialog.Theframeworkdoesthisautomatically
//whentheapplication'smainwindowisnotadialog
SetIcon(m_hIcon,TRUE);//Setbigicon
SetIcon(m_hIcon,FALSE);//Setsmallicon
//TODO:
Addextrainitializationhere
IsDataContent=FALSE;
IsShow=FALSE;
m_Listener.SetParent(this);
m_Server.SetParent(this);
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
voidCSMTPSeverDlg:
:
OnSysCommand(UINTnID,LPARAMlParam)
{
if((nID&0xFFF0)==IDM_ABOUTBOX)
{
CAboutDlgdlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog:
:
OnSysCommand(nID,lParam);
}
}
voidCSMTPSeverDlg:
:
OnAccept()
{
CStringstr;
str.Format("***收到连接请求");
m_List_Smtp.InsertString(-1,str);
if(m_Listener.Accept(m_Server))
{
str.Format("***建立连接");
m_List_Smtp.InsertString(-1,str);
str=_T("220SimpleMailSeverReadyforMail\r\n");
m_Server.Send((LPCTSTR)str,str.GetLength());
str=_T("S:
")+str;
m_List_Smtp.InsertString(-1,str);
m_Server.AsyncSelect(FD_READ);
}
else
m_Server.Close();
}
voidCSMTPSeverDlg:
:
OnReceive()
{
charbuff[65536];
charlocal_host[80];
intnRead;
memset(buff,0,65536);//清空缓冲区接收数据
nRead=m_Server.Receive(buff,65536);
//根据读到的长度
switch(nRead)
{
case0:
m_Server.Close();
break;
caseSOCKET_ERROR:
if(GetLastError()!
=WSAEWOULDBLOCK)
{
AfxMessageBox("Erroroccurred");
m_Server.Close();
}
break;
default:
buff[nRead]=0;//terminatethestring
CStringszTemp;
if(IsDataContent)
{
while(strstr(buff,"\r\n.\r\n")==NULL)
{
str+=buff;
memset(buff,0,65536);
nRead=m_Server.Receive(buff,65536);
}
str+=buff;
CStringTemp;
Temp.Format("%s\r\n\r\n",(LPCTSTR)str.c_str());
m_Edit_Con.SetWindowText(Temp);
Base64_decode(Temp);
szTemp=_T("250Messageacceptedfordelivery\r\n");
m_Server.Send(szTemp,szTemp.GetLength());
szTemp=_T("S:
")+szTemp;
m_List_Smtp.InsertString(-1,szTemp);
szTemp.Empty();
IsDataContent=FALSE;
}
if(strnicmp(buff,"HELO",4)==0)
{
szTemp=buff;
szTemp=_T("C:
")+szTemp;
//m_List_Smtp.InsertString(-1,(LPCTSTR)buff);
m_List_Smtp.InsertString(-1,(LPCTSTR)szTemp);
gethostname(local_host,80);
szTemp.Format(_T("250OK%s\r\n"),local_host);
m_Server.Send((LPCTSTR)szTemp,szTemp.GetLength());
szTemp=_T("S:
")+szTemp;
m_List_Smtp.InsertString(-1,szTemp);
szTemp.Empty();
}
if(strnicmp(buff,"MAILFROM:
",10)==0)
{
szTemp=buff;
szTemp=_T("C:
")+szTemp;
//m_List_Smtp.InsertString(-1,(LPCTSTR)buff);
m_List_Smtp.InsertString(-1,(LPCTSTR)szTemp);
szTemp=_T("250SenderOK\r\n");
m_Server.Send(szTemp,szTemp.GetLength());
szTemp=_T("S:
")+szTemp;
m_List_Smtp.InsertString(-1,szTemp);
szTemp.Empty();
}
if(strnicmp(buff,"RCPTTO:
",8)==0)
{
szTemp=buff;
szTemp=_T("C:
")+szTemp;
//m_List_Smtp.InsertString(-1,(LPCTSTR)buff);
m_List_Smtp.InsertString(-1,(LPCTSTR)szTemp);
szTemp=_T("250ReceiverOK\r\n");
m_Server.Send(szTemp,szTemp.GetLength());
szTemp=_T("S:
")+szTemp;
m_List_Smtp.InsertString(-1,szTemp);
szTemp.Empty();
}
if(strnicmp(buff,"DATA",4)==0)
{
szTemp=buff;
szTemp=_T("C:
")+szTemp;
//m_List_Smtp.InsertString(-1,(LPCTSTR)buff);
m_List_Smtp.InsertString(-1,(LPCTSTR)szTemp);
szTemp=_T("354Goahead.Endwith\r\n");
m_Server.Send(szTemp,szTemp.GetLength());
szTemp=_T("S:
")+szTemp;
m_List_Smtp.InsertString(-1,szTemp);
szTemp.Empty();
IsDataContent=TRUE;
}
if(strnicmp(buff,"QUIT",4)==0)
{
szTemp=buff;
szTemp=_T("C:
")+szTemp;
//m_List_Smtp.InsertString(-1,(LPCTSTR)buff);
m_List_Smtp.InsertString(-1,(LPCTSTR)szTemp);
szTemp=_T("221Quit,Goodbye!
\r\n");
m_Server.Send(szTemp,szTemp.GetLength());
szTemp=_T("S:
")+szTemp;
m_List_Smtp.InsertString(-1,szTemp);
IsShow=TRUE;
}
if(strnicmp(buff,"AUTHLOGIN",10)==0)
{
szTemp=buff;
szTemp=_T("C:
")+szTemp;
//m_List_Smtp.InsertString(-1,(LPCTSTR)buff);
m_List_Smtp.InsertString(-1,(LPCTSTR)szTemp);
szTemp=_T("334dXNlcm5hbWU6\r\n");
m_Server.Send(szTemp,szTemp.GetLength());
szTemp=_T("S:
")+szTemp;
m_List_Smtp.InsertString(-1,szTemp);
szTemp.Empty();
}
if(strnicmp(buff,"bWFu",4)==0)
{
szTemp=buff;
szTemp=_T("C:
")+szTemp;
//m_List_Smtp.InsertString(-1,(LPCTSTR)buff);
m_List_Smtp.InsertString(-1,(LPCTSTR)szTemp);
szTemp=_T("334UGFzc3dvcmQ6\r\n");
m_Server.Send(szTemp,szTemp.GetLength());
szTemp=_T("S:
")+szTemp;
m_List_Smtp.InsertString(-1,szTemp);
szTemp.Empty();
}
if(strnicmp(buff,"bGFp",4)==0)
{
szTemp=buff;
szTemp=_T("C:
")+szTemp;
//m_List_Smtp.InsertString(-1,(LPCTSTR)buff);
m_List_Smtp.InsertString(-1,(LPCTSTR)szTemp);
szTemp=_T("235Authenticationsuccessful\r\n");
m_Server.Send(szTemp,szTemp.GetLength());
szTemp=_T("S:
")+szTemp;
m_List_Smtp.InsertString(-1,szTemp);
szTemp.Empty();
}
}
}
BOOLCSMTPSeverDlg:
:
DestroyWindow()
{
//TODO:
Addyourspecializedcodehereand/orcallthebaseclass
m_Listener.Close();
m_Server.Close();
returnCDialog:
:
DestroyWindow();
}
voidCSMTPSeverDlg:
:
OnClose()
{
m_Server.Close();
CStringstr;
str.Format("Listeningonport%d",25);
m_List_Smtp.InsertString(-1,str);
}
voidCSMTPSeverDlg:
:
OnButtonClose()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
m_Listener.Close();
m_Server.Close();
m_List_Smtp.InsertString(-1,"S:
服务器关闭成功");
}
voidCSMTPSeverDlg:
:
OnButtonOpen()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
BOOLbFlag=m_Listener.Create(25,SOCK_STREAM);
if(!
bFlag)
{
if(GetLastError()!
=WSAEWOULDBLOCK)
{
TCHARszError[256];
wsprintf(szError,"Socket建立失败:
%d",
GetLastError());
m_Listener.Close();
AfxMessageBox(szError);
AfxMessageBox("wrong");
return;
}
}
if(!
m_Listener.Listen
(1))
{
if(GetLastError()!
=WSAEWOULDBLOCK)
{
TCHARszError[256];
wsprintf(szError,"监听失败:
%d",
GetLastError());
m_Listener.Close();
AfxMessageBox(szError);
return;
}
}
m_List_Smtp.InsertString(-1,"*****服务器准备好*****");
m_List_Smtp.InsertString(-1,"************************");
}
voidCSMTPSeverDlg:
:
OnButtonQuit()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
m_Listener.Close();
m_Server.Close();
CDialog:
:
DestroyWindow();
}
//Base64.cpp:
implementationoftheBase64class.
#include"stdafx.h"
#include"SMTPSever.h"
#include"Base64.h"
#ifdef_DEBUG
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#definenewDEBUG_NEW
#endif
Base64:
:
Base64(){}
Base64:
:
~Base64(){}
staticconststd:
:
stringbase64_chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ""abcdefghijklmnopqrstuvwxyz""0123456789+/";
std:
:
stringBase64:
:
base64_encode(conststd:
:
string&s)
{
returnbase64_encode((constunsignedchar*)s.c_str(),s.length());
}
///////////////////////////////////////////解码函数的实现//////////////////////////////////////////
std:
:
stringBase64:
:
base64_decode(unsignedcharconst*encoded_string,unsignedintin_len)
{
inti=0;
intj=0;
intin_=0;
unsignedcharchar_array_4[4],char_array_3[3];
std:
:
stringret;
while(in_len--&&(encoded_string[in_]!
='=')&&is_base64(encoded_string[in_]))
{
char_array_4[i++]=encoded_string[in_];
in_++;
if(i==4)
{
for(i=0;i<4;i++)
char_array_4[i]=base64_chars.find(char_array_4[i]);
char_array_3[0]=(char_array_4[0]<<2)+((ch