POP3客服端实例论文期末作业.docx

上传人:b****5 文档编号:30170726 上传时间:2023-08-05 格式:DOCX 页数:33 大小:4.72MB
下载 相关 举报
POP3客服端实例论文期末作业.docx_第1页
第1页 / 共33页
POP3客服端实例论文期末作业.docx_第2页
第2页 / 共33页
POP3客服端实例论文期末作业.docx_第3页
第3页 / 共33页
POP3客服端实例论文期末作业.docx_第4页
第4页 / 共33页
POP3客服端实例论文期末作业.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

POP3客服端实例论文期末作业.docx

《POP3客服端实例论文期末作业.docx》由会员分享,可在线阅读,更多相关《POP3客服端实例论文期末作业.docx(33页珍藏版)》请在冰豆网上搜索。

POP3客服端实例论文期末作业.docx

POP3客服端实例论文期末作业

目录

(一):

背景知识、主要函数的描述2

一:

POP3简介2

二:

POP3协议工作原理2

三:

程序实现的技术要点(主要函数)3

1.运用Windows的消息驱动机制3

2.通过状态转换来控制会话命令的发布顺序4

3.用结构向量来缓存信件信息4

(二)程序流程图和主要思想5

POP3的会话过程5

POP3程序实例的流程图6

(三)创建应用程序的过程7

1.使用MFCAppWizard创建应用程序框架7

2.为对话框添加控件9

3.定义控件的成员变量10

4.为对话框中的控件对象添加事件响应函数12

5.为类添加其它的成员和创建CAsyncSocket类12

(四)程序代码清单15

(五)程序运行结果27

(一):

背景知识、主要函数的描述

一:

POP3简介

POP适用于C/S结构的脱机模型的电子邮件协议,已发展到第三版,称POP3。

POP3协议允许用户以一定的方式从保存邮件的服务器(即POP3服务器)上取走自己的邮件。

该协议用于接收邮件的双方(客户机、POP3服务器)进行通信。

使用该协议,用户可以脱机阅读信件。

二:

POP3协议工作原理

POP3提供了一种客户机/服务器脱机模型,客户机通过向服务器发送一些命令来完成相应的操作。

客户机能够发送的命令与它所处的状态有关。

协议中定义了三种状态:

即确认状态(AuthorizationState)、处理状态(TransactionState)和更新状态(UpdateState)。

在不同的状态下,客户机可以向服务器发送的命令是有区别的,某些命令还会导致状态的转换。

POP3服务器一般使用的是TCP的110号端口。

当客户机与服务器建立TCP连接时,POP3服务器向客户机发回一个问候,交互过程即进入确认状态。

此时,若客户机提供了自己的身份并成功确认,即由确认状态转入处理状态;在这个状态,用户可用相应的命令处理自己的邮件。

在完成相应的处理过程后客户机发出QUIT命令,则进入更新状态;在此状态下,POP3服务器释放邮件资源并返回一个告别响应;最后关闭TCP连接。

三:

程序实现的技术要点(主要函数)

1.运用Windows的消息驱动机制

除了由MFC创建的应用程序类和对话框类以外,程序从CAsyncSocket类派生了自己的套接字类,并为它添加了OnConnect()、OnClose()和OnReceive()三个事件处理函数。

程序的会话过程几乎完全是由FD_READ消息驱动的。

建立连接后,服务器会返回信息,接到命令后,服务器也会返回信息。

当信息到达客户端套接字的接收缓冲区时,会触发FD_READ消息,并自动执行OnReceive()函数。

该函数接收服务器发来的信息,进行分析处理,然后再发送相应的命令。

这命令又会引来服务器的响应,又会触发客户端的FD_READ消息。

如此周而复始,完成POP会话的全过程。

 

2.通过状态转换来控制会话命令的发布顺序

程序定义了一个枚举类型STATE,并为套接字类定义了一个STATE类型的变量state,用来表示POP会话的实际状态。

容易看出,枚举的成员符号是客户端向POP3服务器发送的命令。

typedefenum

{FIRST=0,USER,PASS,STAT,LIST,RETR,ENDRETR,DELE,GOO}

STATE;

STATEstate;

当用户点击“连接”按钮与服务器建立TCP连接时,将state置为初值FIRST;然后,每当收到服务器的信息,一方面根据会话的当前状态作响应的分析处理,决定应当继续发送哪条命令,另一方面发出下一个命令以后,改变state的值,将它置为该命令的状态对应的值,这就实现了会话过程中的状态转换,并保证会话按照既定的顺序进行。

读者可仔细分析mySock:

:

AnalyzeMsg()函数。

3.用结构向量来缓存信件信息

首先程序定义了一个结构类型,用来缓存一封信件信息。

typedefstruct

{

CStringtext;//存储信件的文本

intmsgSize;//信件的大小

intretrSize;//信件实际下载的大小,在下载过程中动态变化

}MESSAGEPROP;

然后为套接字类定义了一个向量型的成员变量,相当于一个数组,其成员是上述的结构。

vectormsgs;在pop会话中,一次性地将信箱中所有信件的信息转入这个向量,然后可以查阅,存储到文件中,或者进行其他处理。

(2)程序流程图和主要思想

POP3的会话过程

POP3使用C/S工作模式,在接收邮件的用户的PC中,运行POP3程序,在用户所在的ISP的邮件服务器中运行POP3程序,二者之间按照POP3互发消息,POP3的客服机发给POP3服务器的消息成为命令,交互的过程就是POP3回话。

POP3接收者对POP3发送者进行初始化连接,发送者对接收者发送询问指READY,接收者则向发送者提交所要接收数据的要求,发送者做出回应,发送数据。

接收者则开始接收数据。

发送者发送完数据后,提出断开请求,并断开连接。

数据接收过程完成。

POP3程序实例的流程图

POP3接收者对POP3发送者进行初始化连接,接着进行由POP3的发送者对服务器连接,若失败进行错误处理;连接成功,登录自己的邮箱账户,成功后POP3的接收者就可以与发送者进行对话,也即就可以查看自己的邮箱邮件;如失败,依然进行错误处理,直到结束退出。

通过POP3命令查询电子邮件时,客户机可以下载指定的邮件,然后对邮件进行删除或修改操作都无需与服务器进一步交互。

客户机向服务器发送命令并等待响应,POP3命令采用命令行形式,用ASCII码表示。

服务器响应是由一行或多行组成,其中,第一行以ASCII文本+OK,或-ERR开始,分别指出相应的操作是成功还是失败。

(3)创建应用程序的过程

1.使用MFCAppWizard创建应用程序框架

工程名是pop3,应用程序的类型是基于对话框的,对话框的标题是“接收电子邮件客户端程序”,需要WindowsSockets的支持,其它部分接受系统的默认设置就可以。

向导自动为应用程序创建了两个类:

应用程序类:

CPop3App,基类是CWinApp,对应的文件是pop3.h和pop3.cpp。

对话框类:

CPop3Dlg,基类是CDialog,对应的文件是pop3Dlg.h和pop3Dlg.cpp。

2.为对话框添加控件

在程序的主对话框界面中按照图7.6添加相应的可视控件对象,并按照表1.0修改控件的属性。

表1.0对话框中的控件属性

控件类型

控件ID

Caption

静态文本statictext

IDC_STATIC

pop3服务器地址

静态文本statictext

IDC_STATIC

用户名

静态文本statictext

IDC_STATIC

口令

编辑框editbox

IDC_EDIT_SERVER

编辑框editbox

IDC_EDIT_USER

编辑框editbox

IDC_EDIT_PASS

复选框CheckBox

IDC_CHECK_DEL

删除邮箱中的邮件

多文本框RichEditBox

IDC_RICH_INFO

组合选择框ComboBox

IDC_COMB_LIST

(DropList型)

命令按钮button

IDC_BTN_CONN

连接

命令按钮button

IDC_BTN_DISC

断开

命令按钮button

IDCANCAL

取消

命令按钮button

IDC_BTN_VIEW

查看邮件

命令按钮button

IDC_BTN_SAVE

存储

由于属性较多,截取2个图表示一下:

3.定义控件的成员变量

用类向导(ClassWizard)为对话框中的控件对象定义相应的成员变量

控件ID

ControlIDs

变量名称

MemberVariableName

变量类别

Category

变量类型

VariableType

IDC_EDIT_SERVER

m_strServer

Value

CString

IDC_EDIT_USER

m_strUser

Value

CString

IDC_EDIT_PASS

m_strPass

Value

CString

IDC_CHECK_DEL

m_bolDel

Value

BOOL

IDC_COMB_LIST

m_ctrList

Control

CComboBox

IDC_RICH_INFO

m_Info

Value

CString

m_ctrlnfo

Control

CRichEditCtrl

4.为对话框中的控件对象添加事件响应函数

用类向导(ClassWizard)为对话框中的控件对象添加事件响应函数。

控件类型

对象标识ObjectID

消息Message

函数Memberfunctions

命令按钮

IDC_BTN_CONN

BN_CLICKED

OnBtnConn

命令按钮

IDC_BTN_DISC

BN_CLICKED

OnBtnDisc

命令按钮

IDC_MSGLIST

BN_CLICKED

OnDropdownMsglist

命令按钮

IDC_MSGLIST

CBN_CLOSEUP

CloseupMsglist

5.为类添加其它的成员和创建CAsyncSocket类

为了能够捕获并响应socket事件,应创建用户自己的套接字类,可利用类向导添加。

ClassType选择MFCClass,类名为mySock,基类是CAsyncSocket类,创建后对应的文件是mysock.h和mysock.cpp。

在利用类向导为mysock类添加OnConnect,OnClose和OnReceive三个事件处理函数,并为它添加一般的成员函数和变量。

可参看下一小节的程序代码。

最后是,手工添加包含语句以及事件函数和成员函数的代码和分阶段编译执行,进行测试。

添加包含语句以及事件函数和成员函数

分阶段编译执行,进行测试。

(4)程序代码清单

//Pop31.cpp:

implementationoftheCPop3class.

#include"stdafx.h"

#include"Gniazdo.h"

#include"pop3Dlg.h"

#include"Pop31.h"

#ifdef_DEBUG

#undefTHIS_FILE

staticcharTHIS_FILE[]=__FILE__;

#definenewDEBUG_NEW

#endif

#defineMAX_BUFF20000

CPop3:

:

CPop3()

{

state=FIRST;

error="Notconnectedtoserver\r\n";

delAfterRead=FALSE;

}

CPop3:

:

~CPop3()

{

}

voidCPop3:

:

OnReceive(interr)

{

if(err==0)//ifnoerror

{

charbuff[MAX_BUFF];

intrec=Receive(buff,MAX_BUFF);//receivedata

buff[rec]=NULL;

lastMsg=buff;

ParseMsg();//parsedata

}

else

{

error="Errorwhilereceiving!

\r\n";

((DLG)m_pWnd)->Dispatch(S_CLOSE);

}

}

voidCPop3:

:

GetLastMsg(CString&s)

{

s=lastMsg;

}

voidCPop3:

:

SetProp(CStringu,CStringp)

{

user=u;

pass=p;

}

voidCPop3:

:

ParseMsg()

{

CStrings;

strstreamstr;

stringcheck;

str<<(LPCSTR)lastMsg;

str>>check;

if(check=="-ERR")//如果有错误

{

error="Received-ERRfromserver:

"+lastMsg;

Close();//断开然后关闭

return;

}

switch(state)//如果没有错误,则根据不同的响应来处理

{

caseFIRST:

//如果已经连接成功,类初始化的时候state为FIRST

msgs.clear();

((DLG)m_pWnd)->Dispatch(S_RECEIVE);//发送消息到窗体

s.Format("user%s%c%c",user,13,10);

Send((LPCSTR)s,s.GetLength());//发送用户帐号

state=USER;

break;

caseUSER:

((DLG)m_pWnd)->Dispatch(S_RECEIVE);

s.Format("pass%s%c%c",pass,13,10);

Send((LPCSTR)s,s.GetLength());//发送密码

state=PASS;

break;

casePASS:

((DLG)m_pWnd)->Dispatch(S_RECEIVE);

s.Format("stat%c%c",13,10);

Send((LPCSTR)s,s.GetLength());//发送stat命令

state=STAT;

break;

caseSTAT:

{

strings1;

str.seekg(0);

str>>s1>>numMsg>>sizeMsg;//获得数量和大笑

flush(str);

((DLG)m_pWnd)->Dispatch(S_GETNUMMSGS);

((DLG)m_pWnd)->Dispatch(S_GETSIZEMSGS);

if(numMsg>0)//如果有邮件,则发送RETR获得邮件信息

{

state=RETR;

s.Format("retr1%c%c",13,10);

retrMsg=1;

MESSAGEPROPprop;

prop.msgSize=0;

prop.retrSize=0;

prop.text="";

msgs.push_back(prop);

Send((LPCSTR)s,s.GetLength());

}

else//如果没有邮件,则断开

{

error="Nonewmessages\r\n";

Close();

}

}

break;

caseRETR:

{

if(msgs[retrMsg-1].msgSize==0)//如果第一次接收到数据

{

stringtemp;

str.seekg(0);

str>>temp>>msgs[retrMsg-1].msgSize;//得到信息大小

}

msgs[retrMsg-1].text+=lastMsg;//保存数据

msgs[retrMsg-1].retrSize+=lastMsg.GetLength();//增加数据大小

if(msgs[retrMsg-1].retrSize>=msgs[retrMsg-1].msgSize)//判断是否获得所有数据

{//检查是否有其他邮件

if(retrMsg

{

MESSAGEPROPprop;

prop.msgSize=0;

prop.retrSize=0;

prop.text="";

msgs.push_back(prop);

retrMsg++;

s.Format("retr%d%c%c",retrMsg,13,10);//requestanother

Send((LPCSTR)s,s.GetLength());

}

else

{

//如果全部接收完毕,判断是否要删除

if(delAfterRead&&numMsg>0)

{

state=DELE;

delMsg=1;

s.Format("dele%d%c%c",delMsg,13,10);

Send((LPCSTR)s,s.GetLength());

}

else//否则退出

{

state=ENDRETR;

((DLG)m_pWnd)->Dispatch(S_ENDRETR);

error="Sessionended\r\n";

s.Format("quit%c%c",13,10);

Send((LPCSTR)s,s.GetLength());

Close();

}

}

}

}break;

caseDELE:

{

//删除剩余邮件

if(delMsg

{

delMsg++;

s.Format("dele%d%c%c",delMsg,13,10);

Send((LPCSTR)s,s.GetLength());

}

else//如果已经删除完毕

{

((DLG)m_pWnd)->Dispatch(S_ENDRETR);

state=GOON;

error="Deletedallmessages\r\n";

s.Format("quit%c%c",13,10);

Send((LPCSTR)s,s.GetLength());

Close();

}

}

break;

caseGOON:

//默认

default:

((DLG)m_pWnd)->Dispatch(S_RECEIVE);

break;

}

}

voidCPop3:

:

Close()

{

CStringstr;

str.Format("quit%c%c",13,10);

Send((LPCSTR)str,str.GetLength());

((DLG)m_pWnd)->Dispatch(S_CLOSE);

state=FIRST;

CAsyncSocket:

:

Close();

error="Notconnectedtoserver\r\n";

}

CStringCPop3:

:

GetError()

{

returnerror;

}

intCPop3:

:

GetNumMsg()

{

returnnumMsg;

}

BOOLCChooseDlg:

:

OnInitDialog()

{

CDialog:

:

OnInitDialog();

//TODO:

Addextrainitializationhere

CPop3Dlg*par;

par=(CPop3Dlg*)GetParent();//获得父窗体

for(inti=0;ipop3.GetRetrMsgNum();i++)

{

AddToList(par->pop3.GetMsgSubject(i));

}

ctlList.SetCurSel(0);

returnTRUE;

intCPop3:

:

GetSizeMsg()

{

returnsizeMsg;

}

intCPop3:

:

GetRetrMsgNum()

{

returnmsgs.size();

}

CStringCPop3:

:

GetMsg(inti)

{

returnmsgs[i].text;

}

CStringCPop3:

:

GetMsgSubject(inti)

{

intwhere=msgs[i].text.Find("Subject:

");

CStringret;

if(where!

=-1)

ReadLn(where,msgs[i].text,ret);

returnret;

}

voidCPop3:

:

DelAfterRead(BOOLdel)

{

delAfterRead=del;

}

CStringCPop3:

:

GetMsgBody(inti)

{

CStringret;

intwhere=msgs[i].text.Find("\r\n\r\n");

if(where!

=-1)

where+=4;

elsewhere=0;

ret=msgs[i].text.Right(msgs[i].text.GetLength()-where);

ret=ret.Left(ret.GetLength()-3);

returnret;

}

CStringCPop3:

:

GetMsgStuff(inti)

{

CStringret;

intwhere=msgs[i].text.Find("From:

");

ReadLn(where,msgs[i].text,ret);

ret+="\r\n";

where=msgs[i].text.Find("To:

");

if(where!

=-1)

{

ReadLn(where,msgs[i].text,ret);

ret+="\r\n";

}

where=msgs[i].text.Find("Date:

");

if(where!

=-1)

{

ReadLn(where,msgs[i].text,ret);

ret+="\r\n";

}

ret+=GetMsgSubject(i);

ret+="\r\n";

returnret;

}

voidCPop3:

:

ReadLn(intindex,CStringsrc,CString&dst)

{

CStringcomp;

comp=sr

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 艺术创意

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1