网络编程学期论文终稿Word格式.docx
《网络编程学期论文终稿Word格式.docx》由会员分享,可在线阅读,更多相关《网络编程学期论文终稿Word格式.docx(24页珍藏版)》请在冰豆网上搜索。
四、创建应用程序过程
4.1使用MFCAppWizard创建应用程序框架7
4.2为对话框添加控件对象7
4.3编辑控件属性7
4.4定义控件的成员变量8
4.5为对话框总的控件添加事件响应函数9
4.6创建一个普通的类CBase64,用来实现base64编码和解码10
4.7创建从CAsyncSocket类继承的派生类10
五、程序清单
5.1CsmtpApp应用程序类对应的文件10
5.2CSmtpDlg对话框类对应的文件10
5.3mySock套接字类对应的文件13
5.4Cbase64类对应的文件15
六、设计总结19
参考文献19
1.1电子邮件系统简介
电子电子邮件(electronicmail,简称e-mail)是因特网上使用最多的一种应用,它为用户在因特网上设立了存放邮件的电子邮箱,发信人可以随时将电子邮件发送到收信人的电子邮箱,收信人也可以随时上网读取,发信人与收信人以异步的方式通信。
1.2电子邮件系统的构成
一个电子邮件系统包括三个主要的构件,即用户代理,邮件消息传输代理,和电子邮件使用的协议。
电子邮件系统的构成可以用下图来表示:
图1.1电子邮件系统的构成
1.2.1用户代理
用户代理是用户与电子邮件系统的接口,往往是运行于PC机上的一个程序,向用户提供有好的窗口界面,为用户发送或接受邮件。
1.2.2邮件传输代理
邮件传输代理提供电子邮件的传输服务,往往是运行于远端计算机上的服务器软件。
如果考虑到发件与收件是异步发生的两个过程,则又可以将其细分为邮件发送传输代理和邮件接收传输代理。
1.2.3协议
电子邮件传输服务采用的是C/S模式,电子邮件传输的客户机和服务器进程之间进行通信的约定就是协议,主要有两个:
一个是用于发送邮件,即SMTP,是SMTP客户机与SMTP服务器之间通信的约定;
另一个用于接收邮件,即POP3协议,是POP客户机与POP服务器之间通信的约定。
1.3电子邮件系统的实现
通过下面的例子,我们可以分析出电子邮件系统的实现过程:
图1.2电子邮件的发送与接收过程
电子邮件的发送与接收过程可以归纳如下:
(1)用户甲运行Foxmail软件,进入它的窗口用户界面,利用其中发信代理的相关功能,编辑要发送的邮件的内容。
然后填写好收信人的电子邮箱地址,邮件主题等信息后,单击“发送”按钮发送邮件。
(2)Foxmail软件中的SMTP客户机进程向网易网站的SMTP服务器发出连接请求,经过三次握手之后简历TCP连接。
然后进入SMTP客户机与SMTP服务器的会话过程,通过网络,SMTP客户机发出请求,SMTP服务器则以响应做答。
(3)SMTP客户机端进程运行在后台,定期的自动扫描电子邮件缓存队列,一旦收到了邮件,就立即按照邮件收信人的电子邮箱地址向新浪网站的SMTP服务器进程发起建立TCP连接的请求。
同样的经过三次握手之后,建立TCP连接。
经过SMTP客户机与服务器的会话过程,将邮件从网易站点传送到新浪站点,新浪的SMTP服务器则将此邮件放到用户乙的电子邮箱中,等待乙在方便的时候读取邮件。
(4)用户乙要查看自己的邮件时,同样也需运行Foxmail软件,进入窗口用户界面后,选择“收信箱”,就在窗口中看到了自己邮箱中的邮件目录。
并可以对邮件进行多种操作及进一步的处理。
1.4电子邮件系统的特点
通过对电子邮件的构成以及其实现过程的分析,我们可以得出电子邮件系统有如下特点:
(1)它是一种异步的通信系统,与电话等不同的是,通信的双方不需要同时在场。
(2)使用方便,传输迅速,费用低廉,不仅能传输大量的文字信息,而且能够附上声音和图像。
(3)在电子邮件系统的实现中,ESP的服务器必须每天24小时不间断的运行,这样才能保证用户可以随时发送和接收信件,而发送或者接收信件的用户则可以随意。
二、简单邮件传输协议SMTP
2.1简单邮件传输协议SMTP的概述
简单邮件传送协议SMTP(SimpleMailTransferProtocol)是因特网的正式标准,最初在1982年由RFC821规定,目前它的最高版本是RFC2821。
SMTP协议采用C/S模式,专用于电子邮件的发送,规定了发信人把邮件发送到收信人的电子邮箱的全过程中,SMTP客户与SMTP服务器这两个相互通信的进程之间应如何交换信息。
即规定了SMTP的会话过程。
用户直接使用的是用于编写和发送的客户端软件,而通常的SMTP服务器运行在远程站点上。
客户/服务器之间的通信是通过TCP/IP协议进行的。
2.2SMTP客户机与SMTP服务器之间的会话
SMTP客户机与SMTP服务器之间的通信借助TCP连接来进行。
在建立了TCP连接之后,客户机与服务器之间的交换信息的过程称之为SMTP的会话过程。
SMTP服务器并不是邮件的目的地,它只是在邮件的中间传递机构,发送邮件的客户机端软件不需要了解如何把邮件发送到目的地邮箱的服务器上,而只需要告诉具有传递机制的SMTP服务器一些必要的信息。
SMTP客户机与SMTP服务器之间的会话可以如下图表示:
图2.1SMTP客户机与SMTP服务器之间的会话
三、程序设计目的,思想以及技术要求
3.1设计目的
在该程序设计中,smtp主要应该具有如下一些功能:
用户可以利用某个网站的smtp电子邮件发送服务器来发送电子邮件。
你必须是该网站的注册用户,并在该网站申请了免费邮箱。
首先填入smtp服务器地址、邮箱用户名和口令,端口号是25,并填入发信人,发信地址填入你在该网站的免费邮箱地址。
在对话框的右面填入发送电子邮件的相关信息,选择一个附件,然后点击“发送”按钮,程序会与服务器建立TCP连接,然后按照ESMTP协议发送ELHO命令,然后发送用户名和口令,经过验证,进入SMTP会话。
通过命令交互,将邮件和附件发送出去,然后断开连接。
在此过程中,右下方的多文本列表框(RichTextBox)会显示全部的会话信息。
功能完整的发送电子邮件程序最终的用户界面应该如下图所示:
图3.1电子邮件发送客户端程序用户界面
3.2设计思想
电子邮件的通信过程是基于TCP/IP的,所以在Windows环境下,客户机端软件采用WinSock接口来编程,就可以达到和服务器通信的基本目的。
要实现SMTP会话,通常应执行以下步骤:
(1)启动sMTP服务器,在制定的传输层端口监听客户机端得连接请求,为SMTP服务器保留的端口是25.
(2)客户端设置Winsock连接的IP地址或域名,指定端口号,主动发出连接请求,连接到SMTP服务器。
比如,网易的SMTP服务器的域名是,监听端口是25。
(3)服务器接收客户端的连接请求,并发回响应。
客户端应收到类似220BigFoxESMTPserviceready这样的信息,这就说明客户端已经与服务器建立TCP/IP连接,成功地实现了第一步。
(4)客户端和服务器分别向对方发送数据。
(5)客户端或服务器分别读取自己缓冲区中的数据。
(6)以上两步是SMTP会话的主要部分,要按照SMTP协议的规定,按照一定顺序,客户向服务器发送命令,服务器向客户发送应答,以上两步要多次重复。
(7)会话完毕,关闭客户端和服务器之间的连接。
3.3设计技术要点
在此次设计实验中的技术要点主要有:
(1)运用Windows的消息驱动机制实现。
(2)通过状态转换来控制会话命令的发布顺序。
(3)实现身份验证。
四、创建应用程序的过程
4.1.使用MFCAppWizard创建应用程序框架
工程名是smtp,应用程序的类型是基于对话框的,对话框的标题是“电子邮件发送客户端程序”,需要WindowsSockets的支持,其它部分接受系统的默认设置就可以。
向导自动为应用程序创建了两个类:
应用程序类:
CSmtpApp,基类是CWinApp,对应的文件是smtp.h和smtp.cpp。
对话框类:
CSmtpDlg,基类是CDialog,对应文件是smtpDlg.h和smtpDlg.cpp。
4.2为对话框添加控件对象
在创建了应用程序骨架之后,可以布置程序的主对话框。
在MFC界面左方的工作区中选择“ResourceView”选项卡,从中选择Dialog,双击IDC_mtp_DIALOG,右边会出现对话框,左边会出现控制面板,利用控制面板可以方便的在程序的主对话框中添加相应的可视控件对象。
利用各种可视控件对象最终形成的用户界面应如下图所示:
图4.1电子邮件发送客户端程序用户界面
4.3编辑控件属性
完成程序的主对话框之后,按照下表对控件的属性进行修改。
控件类型
控件ID
Caption
静态文本statictext
IDC_STATIC
发信人
发信地址
SMTP服务器
端口
用户名
口令
编辑框editbox
IDC_EDIT_NAME
IDC_EDIT_ADDR
IDC_EDIT_SERVER
IDC_EDIT_PORT
IDC_EDIT_USER
IDC_EDIT_PASS
收信
主题
抄送
暗送
附件
信件内容
IDC_EDIT_RECEIVER
IDC_EDIT_TITLE
IDC_EDIT_CC
IDC_EDIT_BCC
IDC_EDIT_ATTACH
IDC_EDIT_LETTER
命令按钮button
IDC_BTN_VIEW
浏览
smtp会话的状态信息
多文本框RichEditBox
IDC_RICH_LIST
IDOK
发送
IDCANCEL
取消
表4.1控件属性
4.4定义控件的成员变量
选择“MemberVariables”(成员变量)选项卡,用类向导为对话框中的控件定义相应的成员变量。
确认ClassName是CsmtpDlg,用左边的列表框选择一个控件,例如IDC_EDIT_NAME,单击“AddVariables”(添加变量)按钮,会弹出“AddMembeVariable”(添加成员变量)对话框,在弹出的对话框中,将变量名称设置为“m_Name”,将变量的类别设置为“Value”,将变量的类型设置为“Cstring”。
同样的方式,按照下表,为表中的各控件添加成员变量,并且按要求编辑其属性。
ControlIDs
变量名称
MemberVariableName
变量类别
Category
变量类型
VariableType
m_Name
Value
CString
m_Addr
m_Server
m_Port
UINT
m_User
m_Pass
m_Receiver
m_Title
m_CC
m_BCC
m_Attach
m_Letter
IDC_RICH_INFO
m_Info
表4.2控件成员变量
4.5为对话框总的控件对象添加事件响应函数
选择“view”/“ClassWizard”(类向导)命令,进入类向导对话框,选择“MessageMaps”选项卡,确认Classname无误。
从“Message”列表框中选择消息事件,然后单击“AddFunction”按钮,就会看到在“MemberFunction”列表框中看到添加了相应的事件处理函数。
用上述方式,按照下表,为表中的控件对象添加事件相应函数。
对象标识ObjectID
消息Message
函数Memberfunctions
命令按钮
BN_CLICKED
OnBtnView
OnIDOK
表4.2控件对象事件响应函数
4.6创建一个普通的类CBase64,用来实现base64编码和解码。
4.7创建从CAsyncSocket类继承的派生类
为了能够捕获并响应socket事件,应创建用户自己的套接字类,可利用类向导添加。
ClassType选择MFCClass,类名为mySock,基类是CAsyncSocket类,创建后对应的文件是mysock.h和mysock.cpp。
在利用类向导为mysock类添加OnConnect,OnClose和OnReceive三个事件处理函数,并为它添加一般的成员函数和变量。
五、程序清单
5.1CSmtpApp应用程序类对应的文件
smtp.h不动,在smtp.cpp的InitInstance()函数中添加一句初始化多文本框控件的函数。
BOOLCSmtpApp:
:
InitInstance()
{
if(!
AfxSocketInit())
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
returnFALSE;
}
AfxEnableControlContainer();
//MFC自动创建的代码
AfxInitRichEdit();
//用户自己添加的
5.2CSmtpDlg对话框类对应的文件
(1)smtpDlg.h包含文件
#include"
mySock.h"
//自己添加的包含语句
Base64.h"
classCSmtpDlg:
publicCDialog
public:
voidDisp(LONGflag);
//显示信息
voidGetHeader();
//创建电子邮件的头部
mySocksmtpSocket;
//套接字类对象
CSmtpDlg(CWnd*pParent=NULL);
//standardconstructor
enum{IDD=IDD_SMTP_DIALOG};
CStringm_Addr;
//发信地址
CStringm_Attach;
//附件
CStringm_BCC;
//暗送
CStringm_CC;
//抄送
CStringm_Letter;
//信件内容
CStringm_Name;
//发信人
CStringm_Pass;
//口令
UINTm_Port;
//端口
CStringm_Receiver;
//收信
CStringm_Server;
//SMTP服务器
CStringm_Title;
//主题
CStringm_User;
//用户名
CStringm_Info;
//会话状态信息
virtualBOOLOnInitDialog();
afx_msgvoidOnSysCommand(UINTnID,LPARAMlParam);
afx_msgvoidOnPaint();
afx_msgHCURSOROnQueryDragIcon();
afx_msgvoidOnBtnView();
//点击“浏览”按钮时执行
virtualvoidOnOK();
//点击“发送“按钮时执行
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
CBase64coder;
//进行Base64编码的变量
BOOLGetBody(LPSTR&
pszBody,int&
nBodySize);
//构造邮件体
};
(2)smtpDlg.cpp实现文件
stdafx.h"
smtp.h"
smtpDlg.h"
#defineSMTP_MAXLINE76
//CSmtpDlgdialog
CSmtpDlg:
CSmtpDlg(CWnd*pParent/*=NULL*/)
CDialog(CSmtpDlg:
IDD,pParent)
//{{AFX_DATA_INIT(CSmtpDlg)
m_Addr=_T("
"
);
//这一部分是由类向导自动添加的变量初始化代码
m_Attach=_T("
m_BCC=_T("
m_CC=_T("
m_Letter=_T("
m_Name=_T("
m_Pass=_T("
m_Port=0;
m_Receiver=_T("
m_Server=_T("
m_Title=_T("
m_User=_T("
m_Info=_T("
//}}AFX_DATA_INIT
//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32
m_hIcon=AfxGetApp()->
LoadIcon(IDR_MAINFRAME);
//CSmtpDlgmessagehandlers
BOOLCSmtpDlg:
OnInitDialog()
//手工添加的初始化代码
//TODO:
Addextrainitializationhere
wang"
jia@"
//smtp服务器
m_Port=25;
//smtp的保留端口
EXAMPLE"
123456"
yi@"
//收信人地址
UpdateData(FALSE);
//更新用户界面
returnTRUE;
//returnTRUEunlessyousetthefocustoacontrol
//创建电子邮件的头部
voidCSmtpDlg:
GetHeader()
UpdateData(TRUE);
CStringsepa;
CStringsReply;
sReply=_T("
//创建"
Date:
标题行内容
CTimenow(CTime:
GetCurrentTime());
CStringsDate(now.Format(_T("
%a,%d%b%Y%H:
%M:
%S"
)));
sDate+="
+0800(CST)"
;
CStringsBuf(sReply);
if(m_Attach.GetLength())
sReply.Format(_T("
MIME-Version:
1.0\r\n"
));
sBuf+=sReply;
//添加From和to字段,From字段进行了编码
coder.Encode(m_Addr);
From:
=?
gb2312?
B?
%s?
=\r\n"
),coder.EncodedMessage());
To:
%s\r\n"
),m_Receiver);
//添加Date字段
),sDate);
//添加subject字段,进行了编码
//Subject:
GB2312?
XXXXXX=?
=//主题,进行了编码
coder.Encode(m_Tit