《计算机网络课程设计报告-利用C 实现SMTP协议.doc》由会员分享,可在线阅读,更多相关《计算机网络课程设计报告-利用C 实现SMTP协议.doc(34页珍藏版)》请在三一文库上搜索。
1、 计算机网络课程设计报告利用C+实现SMTP协议系 别电子信息系专业名称计算机科学与技术班级学号学生姓名指导教师成 绩2011年 7月 12日第 33 页 东北大学秦皇岛分校课程设计 利用C+实现SMTP协议1.概述SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,是一种提供可靠且有效电子邮件传输的协议。SMTP是建立在FTP文件传输服务上的一种邮件服务,主要用于传输系统之间的邮件信息并提供与来信有关的通知。SMTP目前已是事实上的在Internet传输E-Mail的标准,是一个相对简单的基于文本的协议。在其之上指定了一条消息的一个或多个接收者(在大多数
2、情况下被确定是存在的),然后消息文本就传输了。可以很简单地通过Telnet程序来测试一个SMTP服务器,SMTP使用TCP端口25。要为一个给定的域名决定一个SMTP服务器,需要使用MX(Mail eXchange)DNS。1.1设计题目及实现目标设计题目:利用C+实现SMTP协议;实现目标:实现SMTP协议的基本功能,包括客户机的命令与数据。1.2开发环境简介 本次开发用Visual C+ 6.0作为开发环境。 VC+是微软公司开发的一个IDE(集成开发环境),换句话说,就是使用c+的一个开发平台.有些软件就是这个编出来的.另外还有VB,VF.只是使用不同语言.但是,vc+是Windows平
3、台上的C+编程环境,学习VC要了解很多Windows平台的特性并且还要掌握MFC、ATL、COM等的知识,难度比较大。Windows下编程需要了解Windows的消息机制以及回调(callback)函数的原理;MFC是Win32API的包装类,需要理解文档视图类的结构,窗口类的结构,消息流向等等;COM是代码共享的二进制标准,需要掌握其基本原理等等。VC作为一个主流的开发平台一直深受编程爱好者的喜爱,但是很多人却对它的入门感到难于上青天,究其原因主要是大家对他错误的认识造成的,严格的来说 VC+不是门语言,虽然它和C+之间有密切的关系,如果形象点比喻的话,可以C+看作为一种”工业标准”,而VC
4、+则是某种操作系统平台下的”厂商标准”,而”厂商标准”是在遵循”工业标准”的前提下扩展而来的。VC+应用程序的开发主要有两种模式2.系统设计分析2.1 协议分析SMTP 独立于特定的传输子系统,且只需要可靠有序的数据流信道支持。 SMTP 重要特性之一是其能跨越网络传输邮件,即“ SMTP 邮件中继”。通常, 一个网络可以由公用互联网上 TCP 可相互访问的主机、防火墙分隔的 TCP/IP 网络上 TCP 可相互访问的主机,及其它 LAN/WAN 中的主机利用非 TCP 传输层协议组成。使用 SMTP ,可实现相同网络上处理机之间的邮件传输,也可通过中继器或网关实现某处理机与其它网络之间的邮件
5、传输。 SMTP协议工作原理SMTP是工作在两种情况下:一是电子邮件从客户机传输到服务器:二是从某一个服务器传输到另一个服务器。SMTP也是个请求/响应协议,命令和响应都是基于ASC文本,并以CR和LF符结束。响应包括一个表示返回状态的三位数字代码。SMTP在TCP协议25号端口监听连续请求。 连接和发送过程如下: (1)建立TCP 连接。 (2)客户端发送HELO命令以标识发件人自己的身份,然后客户端发送MAIL命令;服务器端正希望以OK作为响应,表明准备接收。 (3)客户端发送RCPT命令,以标识该电子邮件的计划接收人,可以有多个RCPT行;服务器端则表示是否愿意为收件人接收邮件。 (4)
6、协商结束,发送邮件,用命令DATA发送。 (5)以“.”号表示结束输入内容一起发送出去,结束此次发送,用QUIT命令退出。3.程序核心代码3.1服务器端相关代码:1)、相关核心代码如下:/ SMTPSeverDlg.cpp : implementation file#include stdafx.h#include SMTPSever.h#include SMTPSeverDlg.h#include Picture.h#include / CSMTPSeverDlg message handlersBOOL CSMTPSeverDlg:OnInitDialog()CDialog:OnInitD
7、ialog();/ Add About. menu item to system menu./ IDM_ABOUTBOX must be in the system command range.ASSERT(IDM_ABOUTBOX & 0xFFF0) = IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX AppendMenu(MF_SEPARATOR);pSysMenu-AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);/ Set the icon for this dialog. The framework does th
8、is automatically/ when the applications main window is not a dialogSetIcon(m_hIcon, TRUE);/ Set big iconSetIcon(m_hIcon, FALSE);/ Set small icon/ TODO: Add extra initialization hereIsDataContent = FALSE ;IsShow = FALSE ;m_Listener.SetParent(this);m_Server.SetParent(this);return TRUE; / return TRUE u
9、nless you set the focus to a controlvoid CSMTPSeverDlg:OnSysCommand(UINT nID, LPARAM lParam)if (nID & 0xFFF0) = IDM_ABOUTBOX)CAboutDlg dlgAbout;dlgAbout.DoModal();elseCDialog:OnSysCommand(nID, lParam);void CSMTPSeverDlg:OnAccept()CString str; str.Format(* 收到连接请求); m_List_Smtp.InsertString(-1,str);if
10、(m_Listener.Accept(m_Server)str.Format(* 建立连接);m_List_Smtp.InsertString(-1,str); str = _T(220 Simple Mail Sever Ready for Mailrn); m_Server.Send(LPCTSTR)str,str.GetLength();str = _T(S: )+str;m_List_Smtp.InsertString(-1,str); m_Server.AsyncSelect(FD_READ); elsem_Server.Close();void CSMTPSeverDlg:OnRe
11、ceive() char buff65536; char local_host80; int nRead; memset(buff,0,65536);/清空缓冲区接收数据 nRead = m_Server.Receive(buff, 65536); /根据读到的长度 switch (nRead) case 0: m_Server.Close(); break; case SOCKET_ERROR: if (GetLastError() != WSAEWOULDBLOCK) AfxMessageBox (Error occurred); m_Server.Close(); break; defa
12、ult: buffnRead =0; /terminate the string CString szTemp; if(IsDataContent) while(strstr(buff,rn.rn)=NULL) str+=buff;memset(buff,0,65536);nRead = m_Server.Receive(buff, 65536); str+=buff;CString Temp ;Temp.Format(%srnrn,(LPCTSTR)str.c_str();m_Edit_Con.SetWindowText(Temp);Base64_decode(Temp);szTemp =
13、_T(250 Message accepted for deliveryrn);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
14、.InsertString(-1,(LPCTSTR)szTemp); gethostname(local_host,80); szTemp.Format(_T(250 OK %srn),local_host); m_Server.Send(LPCTSTR)szTemp,szTemp.GetLength(); szTemp = _T(S: )+szTemp; m_List_Smtp.InsertString(-1,szTemp); szTemp.Empty(); if(strnicmp(buff,MAIL FROM:,10)=0) szTemp = buff; szTemp = _T(C: )+
15、szTemp; /m_List_Smtp.InsertString(-1,(LPCTSTR)buff); m_List_Smtp.InsertString(-1,(LPCTSTR)szTemp); szTemp = _T(250 Sender OKrn); m_Server.Send(szTemp,szTemp.GetLength(); szTemp = _T(S: )+szTemp; m_List_Smtp.InsertString(-1,szTemp); szTemp.Empty(); if(strnicmp(buff,RCPT TO:,8)=0) szTemp = buff; szTem
16、p = _T(C: )+szTemp; /m_List_Smtp.InsertString(-1,(LPCTSTR)buff); m_List_Smtp.InsertString(-1,(LPCTSTR)szTemp); szTemp = _T(250 Receiver OKrn); 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 = b
17、uff; szTemp = _T(C: )+szTemp; /m_List_Smtp.InsertString(-1,(LPCTSTR)buff); m_List_Smtp.InsertString(-1,(LPCTSTR)szTemp); szTemp = _T(354 Go ahead. End withrn); m_Server.Send(szTemp,szTemp.GetLength(); szTemp = _T(S: )+szTemp; m_List_Smtp.InsertString(-1,szTemp); szTemp.Empty(); IsDataContent=TRUE; i
18、f(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(221 Quit,Goodbye !rn); m_Server.Send(szTemp,szTemp.GetLength(); szTemp = _T(S: )+szTemp; m_List_Smtp.InsertString(-1,szTemp); IsSh
19、ow = TRUE; if (strnicmp(buff,AUTH LOGIN,10)=0) szTemp = buff; szTemp = _T(C: )+szTemp; /m_List_Smtp.InsertString(-1,(LPCTSTR)buff); m_List_Smtp.InsertString(-1,(LPCTSTR)szTemp); szTemp = _T(334 dXNlcm5hbWU6rn); m_Server.Send(szTemp,szTemp.GetLength(); szTemp = _T(S: )+szTemp; m_List_Smtp.InsertStrin
20、g(-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(334 UGFzc3dvcmQ6rn); m_Server.Send(szTemp,szTemp.GetLength(); szTemp = _T(S: )+szTemp; m_List_Smtp
21、.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(235 Authentication successfulrn); m_Server.Send(szTemp,szTemp.GetLength(); szTemp = _T
22、(S: )+szTemp; m_List_Smtp.InsertString(-1,szTemp); szTemp.Empty(); BOOL CSMTPSeverDlg:DestroyWindow() / TODO: Add your specialized code here and/or call the base classm_Listener.Close();m_Server.Close();return CDialog:DestroyWindow();void CSMTPSeverDlg:OnClose()m_Server.Close();CString str;str.Forma
23、t(Listening on port %d, 25);m_List_Smtp.InsertString(-1,str); void CSMTPSeverDlg:OnButtonClose() / TODO: Add your control notification handler code herem_Listener.Close();m_Server.Close();m_List_Smtp.InsertString(-1,S: 服务器关闭成功);void CSMTPSeverDlg:OnButtonOpen() / TODO: Add your control notification
24、handler code hereBOOL bFlag = m_Listener.Create(25,SOCK_STREAM); if(!bFlag)if (GetLastError() != WSAEWOULDBLOCK) TCHAR szError256; wsprintf(szError, Socket建立失败: %d, GetLastError();m_Listener.Close(); AfxMessageBox(szError);AfxMessageBox(wrong);return ;if(!m_Listener.Listen(1)if (GetLastError() != WS
25、AEWOULDBLOCK) TCHAR szError256; wsprintf(szError, 监听失败: %d, GetLastError(); m_Listener.Close(); AfxMessageBox(szError);return ;m_List_Smtp.InsertString(-1,* 服务器准备好 *);m_List_Smtp.InsertString(-1,*);void CSMTPSeverDlg:OnButtonQuit() / TODO: Add your control notification handler code herem_Listener.Cl
26、ose();m_Server.Close();CDialog:DestroyWindow();/ Base64.cpp: implementation of the Base64 class.#include stdafx.h#include SMTPSever.h#include Base64.h#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE=_FILE_;#define new DEBUG_NEW#endifBase64:Base64()Base64:Base64()static const std:string base64_char
27、s = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/;std:string Base64:base64_encode(const std:string &s) return base64_encode(const unsigned char *)s.c_str(), s.length();/解码函数的实现/std:string Base64:base64_decode(unsigned char const* encoded_string, unsigned int in_len) int i = 0; int
28、 j = 0; int in_ = 0;unsigned char char_array_44, char_array_33;std:string ret; while (in_len- & ( encoded_stringin_ != =) & is_base64(encoded_stringin_) char_array_4i+ = encoded_stringin_; in_+; if (i =4) for (i = 0; i 4; i+) char_array_4i = base64_chars.find(char_array_4i); char_array_30 = (char_ar
29、ray_40 4); /将六个字节和下一个六字节的前两位组成8位解码 char_array_31 = (char_array_41 & 0xf) 2); char_array_32 = (char_array_42 & 0x3) 6) + char_array_43; for (i = 0; (i 3); i+) ret += char_array_3i; i = 0; if (i)/不足24位缓冲区的用0补足再解码 for (j = i; j 4; j+) char_array_4j = 0; for (j = 0; j 4; j+) char_array_4j = base64_chars
30、.find(char_array_4j); char_array_30 = (char_array_40 4); char_array_31 = (char_array_41 & 0xf) 2); char_array_32 = (char_array_42 & 0x3) 6) + char_array_43; for (j = 0; (j 2; /右移 char_array_41 = (char_array_30 & 0x03) 4); char_array_42 = (char_array_31 & 0x0f) 6); char_array_43 = char_array_32 & 0x3
31、f; for(i = 0; (i 4) ; i+) ret += base64_charschar_array_4i; i = 0; if (i) for(j = i; j 2; char_array_41 = (char_array_30 & 0x03) 4); char_array_42 = (char_array_31 & 0x0f) 6); char_array_43 = char_array_32 & 0x3f; for (j = 0; (j i + 1); j+) ret += base64_charschar_array_4j; /这个字符串是 乱码把6个字节放在8个字节的空间里
32、 while(i+ OnReceive();AsyncSelect(FD_READ);CAsyncSocket:OnReceive(nErrorCode);void CServerSocket:OnClose(int nErrorCode) / TODO: Add your specialized code here and/or call the base classif (nErrorCode = 0)(CSMTPSeverDlg*)m_pWnd)-OnClose();CAsyncSocket:OnClose(nErrorCode);/ ListenerSocket.cpp : imple
33、mentation file/#include stdafx.h#include SMTPSever.h#include ListenerSocket.h#include SMTPSeverDlg.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endifCListenerSocket:CListenerSocket()CListenerSocket:CListenerSocket()/ Do not edit the following lines, which are needed by ClassWizard.#if 0BEGIN_MESSAGE_MAP(CListenerSocket, CAsyncSocket)/AFX_MSG_MAP(CListenerSocket)/AFX_MSG_MAPEND_MESSAGE_MAP()#endif/ 0/ CListenerSocket member functionsvoid CListenerSocket:SetParent(CDialog *pWnd)m_pWnd = pWnd;void CListenerSocket:OnAccept(int nErrorCode) if (nErrorCode = 0)
链接地址:https://www.31doc.com/p-5027299.html