vc编写电子邮件程序文件.docx

上传人:b****8 文档编号:28788014 上传时间:2023-07-19 格式:DOCX 页数:19 大小:26.20KB
下载 相关 举报
vc编写电子邮件程序文件.docx_第1页
第1页 / 共19页
vc编写电子邮件程序文件.docx_第2页
第2页 / 共19页
vc编写电子邮件程序文件.docx_第3页
第3页 / 共19页
vc编写电子邮件程序文件.docx_第4页
第4页 / 共19页
vc编写电子邮件程序文件.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

vc编写电子邮件程序文件.docx

《vc编写电子邮件程序文件.docx》由会员分享,可在线阅读,更多相关《vc编写电子邮件程序文件.docx(19页珍藏版)》请在冰豆网上搜索。

vc编写电子邮件程序文件.docx

vc编写电子邮件程序文件

VC++编写电子程序

.diybl. 时间:

2008-08-27 作者:

佚名编辑:

本站点击:

 635[评论]

 

VC++编写电子程序

一、概述

----本文主要讲述如何使用VisualC++用MAPI编写E-mail程序。

MAPI是包含在Windows之中的,

因此不需要安装其他额外的部件。

MAPI有以下三种形式:

SMAPI,SimpleMAPI,简单的MAPI

CMC,CommonMessagingCalls,一般通讯调用

完整的MAPI

----SMAPI和CMC都包含在完整的MAPI中,当用户想执行一些高级操作,比如编写自己的E-mail服务器的时候,

必须使用完整的MAPI。

本文主要阐述如何编写能够收发电子的程序,因此使用SMAPI就足够了。

二、编写电子程序

3-1初始化MAPI

----要使用MAPI,必须首先对它进行初始化。

初始化包括以下三个步骤:

装载MAPI32.DLL动态库

找到想要调用的MAPI函数地址

登录到电子对象

3-1-1装载MAPI32.DLL

----要装载MAPI,用户必须程序运行时动态的装载一个动态库。

LoadLibrary函数提供了此功能,

它定位一个动态库,并返回HINSTANCE局柄(需要保存该句柄)。

LoadLibrary的语法如下:

LoadLibrary(lpLibFileName);

其中lpLibFileName为LPCTSTR结构变量,

是所要调用的库的路径和名称。

程序示例:

//调用MAPI32.DLL并计算函数地址

HINSTANCEhInstMail;

hInstMail=:

:

LoadLibrary(“MAPI32.DLL”);

if(hInstMail==NULL)

{

//错误处理

//受篇幅限制,下面的错误处理部分省略

}

3-1-2确定函数地址

----由于MAPI32.DLL是被动态装载的,因此不知道所要调用的函数地址,也就不能一开始就调用它们,

而要通过函数名获得函数的地址,并在动态库中查找每一个函数并核实。

因此首先必须为这些函数声明指针

程序示例:

//为MAPI32.DLL中的函数声明函数指针

ULONG(PASCAL*lpfnMAPISendMail)(LHANDLElhSession,

ULONGulUIParam,lpMapiMessagelpMessage,

FLAGSflFlags,ULONGulReserved);

ULONG(PASCAL*lpfnMAPIResolveName)(LHANDLElhSession,

ULONGulUIParam,LPTSTRlpszName,

FLAGSulFlags,ULONGulReserved,

lpMapiRecipDescFAR*lppRecip);

ULONG(FARPASCAL*lpfnMAPILogon)(ULONGulUIParam,

LPSTRlpszProfileName,LPSTRlpszPassword,

FLAGSflFlags,ULONGulReserved,

LPLHANDLElplhSession);

ULONG(FARPASCAL*lpfnMAPILogoff)(LHANDLElhSession,

ULONGulUIParam,FLAGSflFlags,

ULONGulReserved);

ULONG(FARPASCAL*lpfnMAPIFreeBuffer)(LPVOIDlpBuffer);

ULONG(FARPASCAL*lpfnMAPIAddress)(LHANDLElhSession,

ULONGulUIParam,LPSTRlpszCaption,

ULONGnEditFields,LPSTRlpszLabels,

ULONGnRecips,lpMapiRecipDesclpRecips,

FLAGSflFlags,ULONGulReserved,

LPULONGlpnNewRecips,

lpMapiRecipDescFAR*lppNewRecips);

ULONG(FARPASCAL*lpfnMAPIFindNext)(LHANDLElhSession,

ULONGulUIParam,LPSTRlpszMessageType,

LPSTRlpszSeedMessageID,FLAGSflFlags,

ULONGulReserved,LPSTRlpszMessageID);

ULONG(FARPASCAL*lpfnMAPIReadMail)(LHANDLElhSession,

ULONGulUIParam,LPSTRlpszMessageID,

FLAGSflFlags,ULONGulReserved,

lpMapiMessageFAR*lppMessage);

----为了决定每一个函数的地址,必须为每一个函数调用GetProcAddress。

GetProcAddress的语法为:

GetProcAddress(hModule,lpProcName);

其中,hModule为HMODULE结构,是所调用DLL模块的句柄;

lpProcName为LPCSTR结构,是函数名称。

程序示例:

//找到MAPI32.DLL函数的地址,并将它们保存在函数指针变量里

(FARPROC&)lpfnMAPISendMail=GetProcAddress(hInstMail,

“MAPISendMail”);

(FARPROC&)lpfnMAPIResolveName=GetProcAddress(

hInstMail,“MAPIResolveName”);

(FARPROC&)lpfnMAPILogon=GetProcAddress(hInstMail,

“MAPILogon”);

(FARPROC&)lpfnMAPILogoff=GetProcAddress(hInstMail,

“MAPILogoff”);

(FARPROC&)lpfnMAPIFreeBuffer=GetProcAddress(

hInstMail,“MAPIFreeBuffer”);

(FARPROC&)lpfnMAPIAddress=GetProcAddress(hInstMail,

“MAPIAddress”);

(FARPROC&)lpfnMAPIFindNext=GetProcAddress(hInstMail,

“MAPIFindNext”);

(FARPROC&)lpfnMAPIReadMail=GetProcAddress(hInstMail,

“MAPIReadMail”);

3-1-3登录到电子对象

----用户必须在电子系统中登录,才能实现MAPI的各种功能。

MAPI提供了登录的三种选择:

登录到一个已经存在的对象。

登录到一个新对象,用编程的方法确定解释新信息。

使用对话框提示用户登录。

----我们通常选择登录到一个已经存在的电子对象,因为网络合作用户通常会保持自己的

电子程序处于激活状态。

登录通常使用MAPI提供的函数lpfnMAPILogon。

lpfnMAPILogon的语法为:

lpfnMAPILogon(lpszProfileName,lpszPassword,flFlags,

ulReserved,lplhSession);

----其中,lpszProfileName指向一个256字符以的登录名称,lpszPassword指向密码,它们均

为LPTSTR结构。

flFlags为FLAGS结构,其值详见表1。

ulReserved必须为0。

lplhSession为输出SMAPI的句柄。

表1:

lpfnMAPILogon函数中flFlags的值

值意义

MAPI_FORCE_DOWNLOAD

在函数调用返回之前下载用户的所有。

如果MAPI_FORCE_DOWNLOAD没有被设置,

那么信件能够在函数调用返回后在后台被下载。

MAPI_NEW_SESSION建立一个新会话,

而不是获得环境的共享会话。

如果MAPI_NEW_SESSION没有被设置,

MAPILogon使用现有的共享会话。

MAPI_LOGON_UI显示一个登录对话框来提示用户输入登录信息。

例如Outlook检查用户电子时便是如此。

MAPI_PASSWORD_UIMAPILogon只允许用户输入电子的密码,

而不许改动账号。

程序示例:

LHANDLElhSession;

ULONGlResult=lpfnMAPILogon(0,NULL,NULL,0,0,

&lhSession);

if(lResult!

=SUCCESS_SUCCESS)

//SUCCESS_SUCCESS在MAPI.H中被定义

{

//错误处理

}

3-2阅读电子

----MAPIFindNext和MAPIReadMail使用与阅读E-mail的两个基本函数。

MAPIFindNext用于定位第一

封或下一封电子并返回标识号,MAPIReadMail返回以该标识号为基础的电子的容。

另外,

一个常用的函数是MAPIFreeBuffer,用于释放存。

3-2-1定位到第一封信

----要找到第一封信,需要使用MAPIFindNext函数,其函数声明如下:

ULONGFARPASCALMAPIFindNext(LHANDLElhSession,

ULONGulUIParam,LPTSTRlpszMessageType,

LPTSTRlpszSeedMessageID,FLAGSflFlags,

ULONGulReserved,LPTSTRlpszMessageID)

----其中,lhSession为提交SMAPI的会话句柄;ulUIParam为父窗体的句柄;lpszMessageType

指向一个字符串,用来鉴别类型,并加以查找;lpszSeedMessageID为指向起始信息ID的指针,

其值为0时,MAPIFindNext获得第一封电子;flFlags的值见表2;ulReserved必须为0;

lpszMessageID为输出值,它是指向信息ID地址的指针。

----表2:

MAPIFindNext函数中flFlags的值

值意义

MAPI_GUARANTEE_FIFO按发送的时间顺序接受电子。

MAPI_LONG_MSGID返回信件标识符可达512字符。

MAPI_UNREAD_ONLY只列举没有阅读过的电子。

程序示例:

//找到第一条没有阅读的电子

charpMessageID[513];

ULONGlResult=lpfnMAPIFindNext(lhSession,NULL,NULL,

NULL,MAPI_LONG_MSGID|MAPI_UNREAD_ONLY,

0,pMessageID);

3-2-2阅读信息

当信件ID被获取后,就可以调用MAPIReadMail

阅读实际的E-mail信息了。

MAPIReadMail的函数声明如下:

ULONGFARPASCALMAPIReadMail(LHANDLElhSession,

ULONGulUIParam,LPTSTRlpszMessageID,

FLAGSflFlags,ULONGulReserved,

lpMapiMessageFAR*lppMessage);

其中,lppMessage为指向MapiMessage的指针;

除flFlags外的其他参数与lpfnFindNext函数的同名参数意义相同,

flFlags参数的值见表3:

表3:

MAPIReadMail函数中flFlags的值:

值意义

MAPI_BODY_AS_FILE将信息写到一个临时文件中,

并且将它作为第一个附件添加到附件列表中。

MAPI_ENVELOPE_ONLY只读取标题。

MAPI_PEEK读完之后不把它标记为“已读”。

MAPI_SUPPRESS_ATTACHMAPIReadMail函数不拷贝附件,

但是将文本写入MapiMessage结构中。

程序示例:

//读取电子

longnFlags=MAPI_SUPPRESS_ATTACH;

if(!

bMarkAsRead)

nFlags=nFlags|MAPI_PEEK;

lResult=lpfnMAPIReadMail(lhSession,NULL,pMessageID,

nFlags,0,&pMessage);

if(lResult!

=SUCCESS_SUCCESS);

returnfalse;

如果调用成功,就可以访问MapiMessage结构了(使用pMessage):

pMessage->ulReserved:

0

pMessage->lpszSubject:

标题

pMessage->lpszNoteText:

信息

pMessage->lpszMessageType:

类型

pMessage->DateReceived:

接收时间

pMessage->lpszConversationID:

所属的会话线程ID

pMessage->flFlags:

其值见表4

表4:

MapiMessage结构中的flFlags

值意义

MAPI_RECEIPT_REQUESTED接收通知被申请。

客户端应用程序在发送消息时设置该项。

MAPI_SENT已被发送。

MAPI_UNREAD是“未读”状态。

pMessage->lpOriginator:

指向MapiRecipDesc结构,包含发件人信息。

pMessage->nRecipCount:

信件者数目。

pMessage->lpRecips:

指向MapiRecipDesc结构数组,包含接收者信息。

pMessage->nFileCount:

附件数量。

pMessage->lpFiles:

指向MapiFileDesc结构数组,

每一个结构包含一个文件附件。

3-2-3释放存

----在访问另一条信件以前应当释放存,否则会出现存泄漏。

程序示例:

//释放存

lpfnMAPIFreeBuffer(pMessage);

3-2-4定位到下一条信件

定位到下一条信件依然使用MAPIFindNext函数,

该函数声明及参数意义详见3-2-1节。

下面示如何定位到下一条信件。

程序示例:

//定位到下一条没有阅读的信件

ULONGlResult=lpfnMAPIFindNext(lhSession,NULL,NULL,

pMessageID,MAPI_LONG_MSGID|MAPI_UNREAD_ONLY,

0,pMessageID);

3-3发送电子

----发送电子的一般步骤:

----1.建立MapiMessage结构对象

----2.调用MAPIResolveName使发送者名称合法

----3.添加附件

----4.调用MAPISendMail发送电子

----5.调用MAPIFreeBuffer释放存

----下面详细分别详细阐述。

3-3-1建立MapiMessage结构对象

----对于MapiMessage结构,3-2-2节已经做过介绍,下面一步步介绍如何设置其中的值:

----1.为MapiMessage对象分配存:

MapiMessagemessage;

Memset(&message,0,sizeof(message));

----2.将ulReserved设置为0:

message.ulReserved=0;

----3.设置信息类型指针lpszMessageType,可以为NULL:

message.lpszMessageType=NULL;

----4.设置信件标题(lpszSubject):

charsubject[512];

strcpy(subject,sSubject);

message.lpszSubject=subject;

----5.设置信件容:

chartext[5000];

strcpy(text,sMessage);

message.lpszNoteText=text;

----6.设置flFlags标识,详见3-2-2节中表4:

message.flFlags=MAPI_SENT;

----7.用一个指向MapiRecipDesc结构的指针设置发送者信息(lpOriginator),或将其设置为NULL:

message.lpOriginator=N

文章出处:

DIY部落(.diybl./course/3_program/vc/vc_js/2008827/137716.html)

++SMTP协议电子传送剖析

2002-11-1918:

05作者:

信息产业部电子第二十二研究所青出处:

yesky责任编辑:

方舟

  摘要:

本文介绍了一种采用SMTP协议规并通过直接使用SMTP协议命令而在程序中实现电子传送的方法。

并在VC++开发环境下给出了部分关键的实现代码。

  前言

  电子服务作为Internet上应用最多和最广的服务项目得到了非常广泛的应用,在网络应用中也起到非常重要的作用。

如同其他的网络服务,电子系统也有其使用的传输协议,包括SMTP(SimpleMailTransferProtocol,简单传输协议)、POP(PostOfficeProtocol,邮局协议)和IMAP(InternetMessageAccessProtocal,消息访问协议)等,这些协议应用于电子的发送和接收。

一些处理软件如OutLookExpress和FoxMail等就是按照SMTP和POP3协议结合WindowsSockets套接字进行设计来收发的。

本文以SMTP协议为研究对象,在VisualC++6.0编程环境下按照SMTP协议通过套接字发送SMTP命令,接收并处理服务器的反馈信息,从而实现对电子的发送。

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

  SMTP协议通讯模型

  SMTP协议是TCP/IP协议族中的一员,主要对如何将电子从发送方地址传送到接收方地址,也即是对传输的规则做了规定。

SMTP协议的通信模型并不复杂,主要工作集中在发送SMTP和接收SMTP上:

首先针对用户发出的请求,由发送SMTP建立一条连接到接收SMTP的双工通讯链路,这里的接收SMTP是相对于发送SMTP而言的,实际上它既可以是最终的接收者也可以是中间传送者。

发送SMTP负责向接收SMTP发送SMTP命令,而接收SMTP则负责接收并反馈应答。

可大致用下面的通讯模型示意图来表示:

  SMTP协议的命令和应答

  从前面的通讯模型可以看出SMTP协议在发送SMTP和接收SMTP之间的会话是靠发送SMTP的SMTP命令和接收SMTP反馈的应答来完成的。

在通讯链路建立后,发送SMTP发送MAIL命令指令发送者,若接收SMTP此时可以接收则作出OK的应答,然后发送SMTP继续发出RCPT命令以确认是否收到,如果接收到就作出OK的应答,否则就发出拒绝接收应答,但这并不会对整个操作造成影响。

双方如此反复多次,直至处理完毕。

SMTP协议共包含10个SMTP命令,列表如下:

SMTP命令

命令说明

HELLO<domain><CRLF>

识别发送方到接收SMTP的一个HELLO命令

MAILFROM:

<reverse-path><CRLF>

<reverse-path>为发送者地址。

此命令告诉接收方一个新发送的开始,并对所有的状态和缓冲区进行初始化。

此命令开始一个传输处理,最终完成将数据传送到一个或多个中。

RCPTTO:

<forward-path><CRLF>

<forward-path>标识各个接收者的地址

DATA<CRLF>

接收SMTP将把其后的行为看作数据去处理,以<CRLF>.<CRLF>标识数据的结尾。

REST<CRLF>

退出/复位当前的传输

NOOP<CRLF>

要求接收SMTP仅做OK应答。

(用于测试)

QUIT<CRLF>

要求接收SMTP返回一个OK应答并关闭传输。

VRFY<string><CRLF>

验证指定的是否存在,由于安全因素,服务器多禁止此命令。

EXPN<string><CRLF>

验证给定的列表是否存在,扩充列表,也常禁止使用。

HELP<CRLF>

查询服务器支持什么命令

注:

<CRLF>为回车、换行,ASCII码分别为13、10(十进制)。

  SMTP协议的每一个命令都会返回一个应答码,应答码的每一个数字都是有特定含义的,如第一位数字为2时表示命令成功;为5表失败;3表没有完成。

一些较复杂的程序利用该特点,首先检查应答码的首数字,并根据其值来决定下一步的动作。

下面将SMTP的应答码列表如下:

应答码

说明

501

参数格式错误

502

命令不可实现

503

错误的命令序列

504

命令参数不可实现

211

系统状态或系统帮助响应

214

帮助信息

220

<domain>服务就绪

221

<domain>服务关闭

421

<domain>服务未就绪,关闭传输信道

250

要求的操作完成

251

用户非本地,将转发向<forward-path>

450

要求的操作未完成,不可用

550

要求的操作未完成,不可用

451

放弃要求的操作;处理过程中出错

551

用户非本地,请尝试<forward-path>

452

系统存储不足,要求的操作未执行

552

过量的存储分配,要求的操作未执行

553

名不可用,要求的操作未执行

354

开始输入,以"."结束

554

操作失败

VC++SMTP协议电子传送剖析

2002-11-1918:

05作者:

信息产业部电子第二十二研究所青出处:

yesky责任编辑:

方舟

  在应用程序中使用SMTP协议

  SMTP协议的会话流程

  在进行程序设计之前有必要弄清SMTP协议的会话流程,其实前面介绍的容已经可以大致勾勒出用SMTP发送的框架了,对于一次普通的发送,其过程大致为:

先建立TCP连接,随后客户端发出HELLO命令以标识发件人自己的身份,并继续由客户端发送MAIL命令,如服务器应答为"OK",可继续发送RCPT命令来标识电子的收件人,在这里可以有多个RCPT行,而服务器端则表示是否愿意为收件人接受该。

在双方协商结束后,用命令DATA将发送出去,其中对表示结束的"."也一并发送出去。

随后结束本次发送过程,以QUIT命令退出。

下面通过一个实

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

当前位置:首页 > 初中教育 > 政史地

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

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