我们在使用163、长通飞华等免费电子邮件的时候,会发现这些电子信箱具有在线收发的功能,即可以通过浏览器发送和接收电子邮件。这些功能一般是通过CGI
实现的,而CGI 技术正在逐渐被ISAPI/NSAPI
技术所取代,下面的例子使用C ++Builder4.0 中的ISAPI/NSAPI
实现了电子邮件的在线接收。使用C ++Builder4 开发Web Server
程序是非常简单的,C ++Builder 4 的VCL
提供了大量的元件和对象,支持Web Server 程序的开发。
本程序由两个文件构成,分别为:
index.htm:接收电子邮件的浏览器界面,放到WEB
服务器的缺省目录下(如:C:\.netpub\wwwroot);ReadMail.dll:在浏览器内显示邮件列表以及指定邮件内容的Web
Server Application。这个动态链结库文件放在可执行文件路径下(如C:\Inetpub\scripts)。
用户在浏览器内通过Web Server 浏览index.htm,输入主机名、端口(一般是110)、用户名、口令后,首先会看到用户的邮件列表,单击相应的邮件序号即可查看邮件内容。
首先建立index.htm,其内容如下:
< html >
< head >
< meta http -equiv="Content -Type"
content="text/html; charset=gb_2312 -80" >
< meta name="GENERATOR" content="Microsoft FrontPage Express 2.0"
>
< title > 邮件查看< /title >
< /head >
< body bgcolor=" #FFFFFF" >
< form action=" /scripts/MailList.dll/MailList"
method="POST" >
< p > 主机:< input type="text" size="20"
name="Host" >< /p >
< p > 端口:< input type="text" size="20"
name="Port" >< /p >
< p > 用户名:< input type="text" size="20"
name="Name" >< /p >
< p > 口令:< input type="password" size="20"
name="Code" >< /p >
< p >< input type="submit" name="B1" value=" 提交"
>< input
type="reset" name="B2" value=" 复原" >< /p >
< /form >
< /body >
< /html >
下面编写ReadMail.dll:
在C ++Builder 中新建一个基于ISAPI 的Web Server Application,手动增加NMPOP31,PageProducer1。在Unit1.h
头文件中定义几个变量:
AnsiString HostName,HostPort,UserName,UserCode;
TStrings *URLData;
// 接受HTTP 请求传递的参数
bool ConnectFlag;
int EmailOrder;
增加一个路径为/MailList 的动作项,其代码如下:
void __fastcall TWebModule1::WebModule1
WebActionItem1Action(TObject *Sender,
TWebRequest *Request, TWebResponse
*Response,bool &Handled)
{
// 接受HTTP 请求传递的参数,
从中获取主机、端口、户名和口令
URLData = NULL;
switch(Request ->MethodType)
{case mtPost:
URLData = Request ->ContentFields;
break;
case mtGet:
URLData = Request ->QueryFields;
break;
}
HostName = URLData ->Values["Host"];
HostPort = URLData ->Values["Port"];
UserName = URLData ->Values["Name"];
UserCode = URLData ->Values["Code"];
// 下面开始连接邮件服务器
NMPOP31 ->AttachFilePath=".";
// 存储邮件路径为当前路径
NMPOP31 ->DeleteOnRead=false;
// 不删除服务器上的副本
NMPOP31 ->ReportLevel=Status_Basic;
//Status 的详细程度
NMPOP31 ->TimeOut=20000;// 设定超时
NMPOP31 ->Host=HostName;
NMPOP31 ->Port=StrToInt(HostPort);
NMPOP31 ->UserID=UserName;
NMPOP31 ->Password=UserCode;
ConnectFlag=true;
NMPOP31 ->Connect();
// 如果连接成功,
则制作邮件列表的HTML 语句
if(ConnectFlag)
{PageProducer1 ->HTMLDoc ->Clear();
PageProducer1 ->HTMLDoc ->Add
("< html >< body > ");
PageProducer1 ->HTMLDoc ->Add
(" 邮件个数" +IntToStr
(NMPOP31 ->MailCount));
if(NMPOP31 ->MailCount)
for(int i=1;i<=NMPOP31 ->MailCount;i ++)
{PageProducer1 ->HTMLDoc ->Add("< a href='");
PageProducer1 ->HTMLDoc ->Add("ReadMail?Mx=");
PageProducer1 ->HTMLDoc ->Add(IntToStr(i));
PageProducer1 ->HTMLDoc ->Add("'>");
PageProducer1 ->HTMLDoc ->Add(IntToStr(i));
PageProducer1 ->HTMLDoc ->Add("< /a >");}
}
PageProducer1 ->HTMLDoc ->Add("< /body >< /html >");
NMPOP31 ->Disconnect();}
else
{PageProducer1 ->HTMLDoc ->Clear();
PageProducer1 ->HTMLDoc ->Add("< html >
");
PageProducer1 ->HTMLDoc ->Add
(" 连接服务器失败!");
PageProducer1 ->HTMLDoc ->Add("< /body >
< /html >");}
// 将邮件列表的HTML 语句发送给浏览器
Response ->Content = PageProducer1 ->Content( );
}
// --------------
以上部分程序完成了显示邮件服务器邮件列表的功能。接下来,再增加一个路径为/MailList
的动作项,它的功能是显示指定的邮件内容。
void __fastcall TWebModule1::WebModule1
WebActionItem2Action(TObject *Sender,
TWebRequest *Request, TWebResponse
*Response,bool &Handled)
{
// 接受HTTP 请求传递的参数,
从中获取用户名和口令、
欲查看的邮件序号
URLData = NULL;
switch(Request ->MethodType)
{case mtPost:
URLData = Request ->ContentFields;
break;
case mtGet:
URLData = Request ->QueryFields;
break;}
EmailOrder = StrToInt(URLData ->Values["Mx"]);
// 下面开始连接邮件服务器
NMPOP31 ->AttachFilePath=".";
// 存储邮件路径为当前路径
NMPOP31 ->DeleteOnRead=false;
// 不删除服务器上的副本
NMPOP31 ->ReportLevel=Status_Basic;
//Status 的详细程度
NMPOP31 ->TimeOut=20000; // 设定超时
NMPOP31 ->Host=HostName;
NMPOP31 ->Port=StrToInt(HostPort);
NMPOP31 ->UserID=UserName;
NMPOP31 ->Password=UserCode;
ConnectFlag=true;
NMPOP31 ->Connect();
// 如果连接成功,打开指定的邮件
if(ConnectFlag)
{PageProducer1 ->HTMLDoc ->Clear();
PageProducer1 ->HTMLDoc ->Add
("< html >< body >");
PageProducer1 ->HTMLDoc ->Add
(" 第" +IntToStr(EmailOrder) +
" 个邮件内容:");
NMPOP31 ->GetMailMessage(EmailOrder);
PageProducer1 ->HTMLDoc ->AddStrings
(NMPOP31 ->MailMessage ->Head);
PageProducer1 ->HTMLDoc ->AddStrings
(NMPOP31 ->MailMessage ->Body);
PageProducer1 ->HTMLDoc ->Add("< /body >
< /html >");
NMPOP31 ->Disconnect(); }
else
{PageProducer1 ->HTMLDoc ->Clear();
PageProducer1 ->HTMLDoc ->Add
("< html >< body >");
PageProducer1 ->HTMLDoc ->Add
(" 连接服务器失败!");
PageProducer1 ->HTMLDoc ->Add
("< /body >< /html >");}
// 将显示指定邮件内容的
HTML 语句发送给浏览器
Response ->Content = PageProducer1 ->
Content( );
}
// -------------
最后在NMPOP31 的ConnectionFailed
事件中加入:
void __fastcall TWebModule1::NMPOP31
ConnectionFailed(TObject *Sender)
{
ConnectFlag=false;
}
// -------------
编译完成后,将生成的DLL 文件更名为和HTML
文件相对应的名称(如:ReadMail.dll),放在C:\Inetpub\scripts
即可。以上程序在Pwin98 +PWS4 上通过。
此外,本程序还有不足之处,比如只能查看内容为纯文本格式的邮件,没有处理异常的能力。读者感兴趣的话,不妨改进。