1
第 14章 开发 Internet应用程序
Internet应用程序的开发通常包括
Internet服务端和客户端的应用程序,
Microsoft提供了大量的 API函数来支持这
两种程序,客户端应用程序主要通过
Internet协议 (如 Gopher,FTP,HTTP等 )来从
网络服务器上获取数据,提供访问
Internet的功能,服务器端应用程序则用
来支持 HTTP,FTP或 Gopher等类型的服
务
2
14.1 Internet应用程序开发的几种类型
使用 WinInet类开发 Internet应用程序,WinInet类支持
HTTP,FTP和 Gopher等标准的协议
使用 Windows Socket开发 Internet应用程序,Winsock
标准定义了一个 DLL接口来连接 Internet,MFC使用
CAsyncSocket和 CSocket类对接口进行了封装。
使用消息收发 API(MAPI,Message API) 开发 Internet应
用程序,使用 MAPI可以很方便的向其他应用程序发
送电子邮件、语音邮件或传真等功能
3
14.2 WinInet开发简介 用 WinInet开发程序的优点
隐藏协议细节,简化编程,可不必深入了解协议,而
使用 WinSocket编程,需理解网络通信及协议基本原理
熟悉的编程接口,WinInet API函数和很多 WinAPI函数很
相似,这对有编程经验的程序员来说是很方便的。
稳定性好,不要求程序与底层直接联系,WinInet隐藏
了协议的具体细节,使得程序不必直接使用各种协议
支持数据缓存,WinInet函数为所有的协议提供缓存
能力,程序员只需关心数据而不用去管理数据缓存
支持多线程,由于 WinInet函数在内部处理多线程的并
发问题,因此 WinInet函数支持多线程,在多线程中可
以调用各种 WinInet函数而不用担心发生问题或死锁
4
14.3 WinInet类介绍
WinInet类是一个总称,目前的版本中分为四组
? CInternetSession类
? CInternetConnection (连接类 )
? CFileFind类 (Internet文件查找类 )
? CInternetFile类和 CGopherLocator类
5
14.3.1 CInternetSession类
CInternetSession类直接继承自 CObject类,
该类用来建立与某个 Internet服务器的会
话。还可以向代理服务器描述连接,如
果应用程序所使用的 Internet连接必须保
持一段时间,则可以在 CWinApp类中创
建相应的 CInternetSession成员
6
QueryOption 提供一个可能的错误检测判断
SetOption 设置 Internet会话的选项
OpenURL 设置 URL,并对其进行分析
GetFtpConnection 打开一个 FTP会话并进行连接
GetHttpConnection 打开 HTTP服务器并进行连接
GetGopherConnection 打开 Gopher服务器并进行连接
EnableStatusCallback 建立异步操作的状态回调
ServiceTypeFromHandle 通过 Internet句柄返回服务器类型
GetContext 获取 Internet和应用程序会话句柄
Close 关闭 Internet连接
CInternetSession类
成员函数
7
14.3.2 CInternetConnection类
包括 CInternetConnection类及其派生类
CHttpConnection,CFtpConnection和
CGopherConnection类,
这些类帮助用户管理与 Internet服务器的连接,
同时还提供一些函数完成和响应服务器的通
信
8
CInternetConnection,用于管理与 Internet服务器的连接
CFtpConnection,用于管理与 FTP服务器的连接, 可以
对服务器上的文件和目录进行直接操作
CGopherConnection,管理与 Gopher服务器的连接
CHttpConnection,管理与 HTTP服务器的连接
连接类及其
派生类
9
14.3.3 CInternetFile类
包括 CInternetFile 类 及 其 派 生 类 CHttpFile,
CGopherFile。 这些类实现对远程系统上的文
件的存取工作 。
文 件 类 还 包 含 CFileFind 类 及 其 派 生 类
CFtpFileFind,CGopherFileFind类 。 CFileFind类
直接继承于 CObject类, 这些类实现对本地和
远程系统上的文件的搜索和定位工作 。
10
CInternetFile:允许对使用 Internet协议的远程系统中的
文件进行操作
CGopherFile:为在 Gopher服务器上进行文件检索和读取
操作提供支持
CHttpFile:提供对 HTTP服务器上的文件进行操作的支持
CFindFile:文文件检索提供支持
CFtpFileFind:为在 FTP服务器上进行的文件检索操作提
供支持
CGopherFileFind:为在 Gopher服务器上进行的文件检索
操作提供支持
文件类说明
11
14.3.4 CGopherLocator类
在从 Gopher服务器中获取信息之前,
必须先获得该服务器的定位器,而
CGopherLocator类的主要功能就是从
Gopher服务器中得到定位并确定定位
器的类型 。
12
14.4 用 WinInet类开发应用程序
编写支持 Internet的应用程序一般步骤:
(1)创建一个 CInternetSession对象,由于 Internet
会话是通过 CInternetConection类的对象实现的,
因此首先要创建一个 CInternetSession对象,建
立一个 Internet会话。
(2)建立与服务器的连接,客户应用程序要与服
务器协同工作,在创建了 CInternetSession对象
后,就需要建立到服务器的连接。根据不同的
协议,可选用 GetFtpConnect,GetHttpConnect和
GetGopherConnect三种方法中的一种。
13
(3)查询或设置 Internet选项,在连接时,有时还
要查询或设置 Internet 选项,这个工作可以通过
QueryOption或 SetOption函数来完成。
(4)向用户反馈当前数据处理的进程信息,有时
客户的应用程序在进行某些操作时,要耗费较
长的时间,因此需要向用户反馈当前的状态,
这个工作由 EnableStatusCallback函数来完成,
此时还要重载 OnStatusCallBack函数以实现回调
函数的功能。
14
(5)创建 CInternetFile实例,调用 CInternetSession
类的成员函数 OpenURL建立与服务器的连接,
函数返回一个 CInternetFile指针。
(6)文件读写操作,调用 CInternetFile::Read或
CInternetFile::Write函数对所得到得服务器文件
进行读写操作。
(7)异常处理,为提高应用程序的可靠性和容错
性,必须对可能出现的问题进行处理,这种处
理通常是通过调用 CInternetException类的对象对
目前可知的异常进行处理。
(8) 结束,调用 CInternetSession::Close结束会话
并销毁 CInternetSession对象。
15
14.5 WinInet类编程实例
【 例 14-1】 利用 WinInet类编写 Internet应用程序。
在 URL编辑框中写入地址,单击,Http”、
,Ftp”或,Gopher”等按钮可在编辑框中显示
查询到的相应服务器的信息
编辑框 1 IDC_EDIT_URL
编辑框 2 IDC_EDIT_RESULT
下压式按钮 IDC_BUTTON_HTTP
下压式按钮 IDC_ BUTTON _FTP
下压式按钮 IDC_ BUTTON _GOPHER
下压式按钮 IDCANCEL
静态文本 IDC_STATIC
组框 IDC_STATIC
16
给界面对象连接接变量
17
(a) 给应用程序增加一个自定义的类,单击 Insert?New
Class菜单,添加新类类名为 CMyWinInetClass,系统会自
动在项目中增加 MyWinInetClass.cpp和 MyWinInetClass.h两
个文件
18
(b)在新加入的类中增加如下三个 public的成员函
数, 在头文件 MyWinInetClass.h中可看到这些
函数 。
CString ConnectFtp(const CString sUrl);
//完成连接 Ftp功能的函数
CString ConnectHttp(const CString sUrl);
//完成连接 Http功能的函数
CString ConnectGopher(const CString sUrl);
//完成连接 Gopher功能的函数
19
为了建立 Internet的会话, 新增加的 CmyWinInetClass类
中加入一个 private型成员变量 m_session:
CInternetSession m_session; //建立 Internet会话
由于在上面定义了一个 CWinInet类的对象, 所以还需
要在 MyWinInetClass.h头文件中加入如下代码:
#include "afxinet.h"
#include "wininet.h"
20
为 CMyWinInetClass类添加三个用于连接的成员函数,它
们分别是 ConnectFtp,ConnectHttp和 ConnectGopher。
CString CMyWinInetClass::ConnectFtp(const CString sUrl)
{ CString sResult; //存储连接信息的字符串
CFtpConnection *Ftpconnection=NULL;
sResult="";
sResult=sResult+"Trying to connect Ftp sites"+sUrl+"\r\n";
Ftpconnection=m_session.GetFtpConnection(sUrl);
//建立到 Ftp服务器的连接
21
if(Ftpconnection)
{ sResult=sResult+"Connection established.\r\n";
CString sCurDir;
Ftpconnection->GetCurrentDirectory(sCurDir);
//得到 Ftp服务器的当前目录
sResult=sResult+"current directory is"+sCurDir+"\r\n";
Ftpconnection->Close(); //关闭连接
}
else
{
sResult=sResult+"There are some errors in finding this Ftp sites";
}
return sResult; }
22
CString CMyWinInetClass::ConnectHttp(const CString sUrl)
{ CString sResult;
CInternetFile *hHttpFile=NULL;
sResult="";
sResult=sResult+"Trying to connect Http sites"+sUrl+"\r\n";
hHttpFile=(CInternetFile *)m_session.OpenURL(sUrl);
//得到文件指针
if(hHttpFile)
{ sResult=sResult+"Connection established.\r\n";
CString sLine;
while(hHttpFile->ReadString(sLine)) //读取 Http服务器上的内容
sResult=sResult+sLine+"\r\n";
hHttpFile->Close(); //关闭连接
}
else
sResult=sResult+"There are some errors in finding this Http
sites";
return sResult;
}
23
CString CMyWinInetClass::ConnectGopher(const CString sUrl)
{ CString sResult;
CInternetFile *hGopherFile=NULL;
sResult="";
sResult=sResult+"Trying to connect Gopher sites"+sUrl+"\r\n";
hGopherFile=(CInternetFile *)m_session.OpenURL(sUrl);
//得到文件指针
if(hGopherFile)
{ sResult=sResult+"Connection established.\r\n";
CString sLine;
while(hGopherFile->ReadString(sLine)) //读取 Gopher服务器内容
sResult=sResult+sLine+"\r\n";
hGopherFile->Close(); //结束连接
}
else
sResult=sResult+"There are some errors in finding this Gopher sites";
return sResult;
}
24
在 CMyInternetDlg类中增加一个 public成员变量
CMyWinInetClass m_WinInetClass;
变量 m_WinInetClass是 CMyWinInetClass类的一个
对象,所以还要在 WinInetDlg.h头文件加入自定
义类的头文件:
#include "MyWinInetClass.h"
25
三个消息处理函数增加代码如下:
void CWinInetDlg::OnButtonFtp()
{ UpdateData(TRUE); //从对话框读入地址信息 m_Url
m_EditResult="";
//调用自定义类的成员函数,连接 Ftp服务器,m_Url为地址
m_EditResult=m_EditResult+m_WinInetClass.ConnectFtp(m_Url);
UpdateData(FALSE);
}
void CWinInetDlg::OnButtonHttp()
{ UpdateData(TRUE); //从对话框读入地址信息 m_Url
m_EditResult="";
//调用自定义类的成员函数,连接 Http服务器,m_Url为地址
m_EditResult=m_EditResult+m_WinInetClass.ConnectHttp(m_Url);
UpdateData(FALSE);
}
26
void CWinInetDlg::OnButtonGopher()
{
UpdateData(TRUE); //从对话框读入地址信息 m_Url
m_EditResult="";
//调用自定义类的成员函数,连接 Gopher服务器,m_Url为地址
m_EditResult=m_EditResult+m_WinInetClass.ConnectGopher(m_Url);
UpdateData(FALSE);
}
27
28
29
第 14章 开发 Internet应用程序
Internet应用程序的开发通常包括
Internet服务端和客户端的应用程序,
Microsoft提供了大量的 API函数来支持这
两种程序,客户端应用程序主要通过
Internet协议 (如 Gopher,FTP,HTTP等 )来从
网络服务器上获取数据,提供访问
Internet的功能,服务器端应用程序则用
来支持 HTTP,FTP或 Gopher等类型的服
务
2
14.1 Internet应用程序开发的几种类型
使用 WinInet类开发 Internet应用程序,WinInet类支持
HTTP,FTP和 Gopher等标准的协议
使用 Windows Socket开发 Internet应用程序,Winsock
标准定义了一个 DLL接口来连接 Internet,MFC使用
CAsyncSocket和 CSocket类对接口进行了封装。
使用消息收发 API(MAPI,Message API) 开发 Internet应
用程序,使用 MAPI可以很方便的向其他应用程序发
送电子邮件、语音邮件或传真等功能
3
14.2 WinInet开发简介 用 WinInet开发程序的优点
隐藏协议细节,简化编程,可不必深入了解协议,而
使用 WinSocket编程,需理解网络通信及协议基本原理
熟悉的编程接口,WinInet API函数和很多 WinAPI函数很
相似,这对有编程经验的程序员来说是很方便的。
稳定性好,不要求程序与底层直接联系,WinInet隐藏
了协议的具体细节,使得程序不必直接使用各种协议
支持数据缓存,WinInet函数为所有的协议提供缓存
能力,程序员只需关心数据而不用去管理数据缓存
支持多线程,由于 WinInet函数在内部处理多线程的并
发问题,因此 WinInet函数支持多线程,在多线程中可
以调用各种 WinInet函数而不用担心发生问题或死锁
4
14.3 WinInet类介绍
WinInet类是一个总称,目前的版本中分为四组
? CInternetSession类
? CInternetConnection (连接类 )
? CFileFind类 (Internet文件查找类 )
? CInternetFile类和 CGopherLocator类
5
14.3.1 CInternetSession类
CInternetSession类直接继承自 CObject类,
该类用来建立与某个 Internet服务器的会
话。还可以向代理服务器描述连接,如
果应用程序所使用的 Internet连接必须保
持一段时间,则可以在 CWinApp类中创
建相应的 CInternetSession成员
6
QueryOption 提供一个可能的错误检测判断
SetOption 设置 Internet会话的选项
OpenURL 设置 URL,并对其进行分析
GetFtpConnection 打开一个 FTP会话并进行连接
GetHttpConnection 打开 HTTP服务器并进行连接
GetGopherConnection 打开 Gopher服务器并进行连接
EnableStatusCallback 建立异步操作的状态回调
ServiceTypeFromHandle 通过 Internet句柄返回服务器类型
GetContext 获取 Internet和应用程序会话句柄
Close 关闭 Internet连接
CInternetSession类
成员函数
7
14.3.2 CInternetConnection类
包括 CInternetConnection类及其派生类
CHttpConnection,CFtpConnection和
CGopherConnection类,
这些类帮助用户管理与 Internet服务器的连接,
同时还提供一些函数完成和响应服务器的通
信
8
CInternetConnection,用于管理与 Internet服务器的连接
CFtpConnection,用于管理与 FTP服务器的连接, 可以
对服务器上的文件和目录进行直接操作
CGopherConnection,管理与 Gopher服务器的连接
CHttpConnection,管理与 HTTP服务器的连接
连接类及其
派生类
9
14.3.3 CInternetFile类
包括 CInternetFile 类 及 其 派 生 类 CHttpFile,
CGopherFile。 这些类实现对远程系统上的文
件的存取工作 。
文 件 类 还 包 含 CFileFind 类 及 其 派 生 类
CFtpFileFind,CGopherFileFind类 。 CFileFind类
直接继承于 CObject类, 这些类实现对本地和
远程系统上的文件的搜索和定位工作 。
10
CInternetFile:允许对使用 Internet协议的远程系统中的
文件进行操作
CGopherFile:为在 Gopher服务器上进行文件检索和读取
操作提供支持
CHttpFile:提供对 HTTP服务器上的文件进行操作的支持
CFindFile:文文件检索提供支持
CFtpFileFind:为在 FTP服务器上进行的文件检索操作提
供支持
CGopherFileFind:为在 Gopher服务器上进行的文件检索
操作提供支持
文件类说明
11
14.3.4 CGopherLocator类
在从 Gopher服务器中获取信息之前,
必须先获得该服务器的定位器,而
CGopherLocator类的主要功能就是从
Gopher服务器中得到定位并确定定位
器的类型 。
12
14.4 用 WinInet类开发应用程序
编写支持 Internet的应用程序一般步骤:
(1)创建一个 CInternetSession对象,由于 Internet
会话是通过 CInternetConection类的对象实现的,
因此首先要创建一个 CInternetSession对象,建
立一个 Internet会话。
(2)建立与服务器的连接,客户应用程序要与服
务器协同工作,在创建了 CInternetSession对象
后,就需要建立到服务器的连接。根据不同的
协议,可选用 GetFtpConnect,GetHttpConnect和
GetGopherConnect三种方法中的一种。
13
(3)查询或设置 Internet选项,在连接时,有时还
要查询或设置 Internet 选项,这个工作可以通过
QueryOption或 SetOption函数来完成。
(4)向用户反馈当前数据处理的进程信息,有时
客户的应用程序在进行某些操作时,要耗费较
长的时间,因此需要向用户反馈当前的状态,
这个工作由 EnableStatusCallback函数来完成,
此时还要重载 OnStatusCallBack函数以实现回调
函数的功能。
14
(5)创建 CInternetFile实例,调用 CInternetSession
类的成员函数 OpenURL建立与服务器的连接,
函数返回一个 CInternetFile指针。
(6)文件读写操作,调用 CInternetFile::Read或
CInternetFile::Write函数对所得到得服务器文件
进行读写操作。
(7)异常处理,为提高应用程序的可靠性和容错
性,必须对可能出现的问题进行处理,这种处
理通常是通过调用 CInternetException类的对象对
目前可知的异常进行处理。
(8) 结束,调用 CInternetSession::Close结束会话
并销毁 CInternetSession对象。
15
14.5 WinInet类编程实例
【 例 14-1】 利用 WinInet类编写 Internet应用程序。
在 URL编辑框中写入地址,单击,Http”、
,Ftp”或,Gopher”等按钮可在编辑框中显示
查询到的相应服务器的信息
编辑框 1 IDC_EDIT_URL
编辑框 2 IDC_EDIT_RESULT
下压式按钮 IDC_BUTTON_HTTP
下压式按钮 IDC_ BUTTON _FTP
下压式按钮 IDC_ BUTTON _GOPHER
下压式按钮 IDCANCEL
静态文本 IDC_STATIC
组框 IDC_STATIC
16
给界面对象连接接变量
17
(a) 给应用程序增加一个自定义的类,单击 Insert?New
Class菜单,添加新类类名为 CMyWinInetClass,系统会自
动在项目中增加 MyWinInetClass.cpp和 MyWinInetClass.h两
个文件
18
(b)在新加入的类中增加如下三个 public的成员函
数, 在头文件 MyWinInetClass.h中可看到这些
函数 。
CString ConnectFtp(const CString sUrl);
//完成连接 Ftp功能的函数
CString ConnectHttp(const CString sUrl);
//完成连接 Http功能的函数
CString ConnectGopher(const CString sUrl);
//完成连接 Gopher功能的函数
19
为了建立 Internet的会话, 新增加的 CmyWinInetClass类
中加入一个 private型成员变量 m_session:
CInternetSession m_session; //建立 Internet会话
由于在上面定义了一个 CWinInet类的对象, 所以还需
要在 MyWinInetClass.h头文件中加入如下代码:
#include "afxinet.h"
#include "wininet.h"
20
为 CMyWinInetClass类添加三个用于连接的成员函数,它
们分别是 ConnectFtp,ConnectHttp和 ConnectGopher。
CString CMyWinInetClass::ConnectFtp(const CString sUrl)
{ CString sResult; //存储连接信息的字符串
CFtpConnection *Ftpconnection=NULL;
sResult="";
sResult=sResult+"Trying to connect Ftp sites"+sUrl+"\r\n";
Ftpconnection=m_session.GetFtpConnection(sUrl);
//建立到 Ftp服务器的连接
21
if(Ftpconnection)
{ sResult=sResult+"Connection established.\r\n";
CString sCurDir;
Ftpconnection->GetCurrentDirectory(sCurDir);
//得到 Ftp服务器的当前目录
sResult=sResult+"current directory is"+sCurDir+"\r\n";
Ftpconnection->Close(); //关闭连接
}
else
{
sResult=sResult+"There are some errors in finding this Ftp sites";
}
return sResult; }
22
CString CMyWinInetClass::ConnectHttp(const CString sUrl)
{ CString sResult;
CInternetFile *hHttpFile=NULL;
sResult="";
sResult=sResult+"Trying to connect Http sites"+sUrl+"\r\n";
hHttpFile=(CInternetFile *)m_session.OpenURL(sUrl);
//得到文件指针
if(hHttpFile)
{ sResult=sResult+"Connection established.\r\n";
CString sLine;
while(hHttpFile->ReadString(sLine)) //读取 Http服务器上的内容
sResult=sResult+sLine+"\r\n";
hHttpFile->Close(); //关闭连接
}
else
sResult=sResult+"There are some errors in finding this Http
sites";
return sResult;
}
23
CString CMyWinInetClass::ConnectGopher(const CString sUrl)
{ CString sResult;
CInternetFile *hGopherFile=NULL;
sResult="";
sResult=sResult+"Trying to connect Gopher sites"+sUrl+"\r\n";
hGopherFile=(CInternetFile *)m_session.OpenURL(sUrl);
//得到文件指针
if(hGopherFile)
{ sResult=sResult+"Connection established.\r\n";
CString sLine;
while(hGopherFile->ReadString(sLine)) //读取 Gopher服务器内容
sResult=sResult+sLine+"\r\n";
hGopherFile->Close(); //结束连接
}
else
sResult=sResult+"There are some errors in finding this Gopher sites";
return sResult;
}
24
在 CMyInternetDlg类中增加一个 public成员变量
CMyWinInetClass m_WinInetClass;
变量 m_WinInetClass是 CMyWinInetClass类的一个
对象,所以还要在 WinInetDlg.h头文件加入自定
义类的头文件:
#include "MyWinInetClass.h"
25
三个消息处理函数增加代码如下:
void CWinInetDlg::OnButtonFtp()
{ UpdateData(TRUE); //从对话框读入地址信息 m_Url
m_EditResult="";
//调用自定义类的成员函数,连接 Ftp服务器,m_Url为地址
m_EditResult=m_EditResult+m_WinInetClass.ConnectFtp(m_Url);
UpdateData(FALSE);
}
void CWinInetDlg::OnButtonHttp()
{ UpdateData(TRUE); //从对话框读入地址信息 m_Url
m_EditResult="";
//调用自定义类的成员函数,连接 Http服务器,m_Url为地址
m_EditResult=m_EditResult+m_WinInetClass.ConnectHttp(m_Url);
UpdateData(FALSE);
}
26
void CWinInetDlg::OnButtonGopher()
{
UpdateData(TRUE); //从对话框读入地址信息 m_Url
m_EditResult="";
//调用自定义类的成员函数,连接 Gopher服务器,m_Url为地址
m_EditResult=m_EditResult+m_WinInetClass.ConnectGopher(m_Url);
UpdateData(FALSE);
}
27
28
29