一、概述
一个 Internet 客户端程序的目的是通过 Internet 协议如: HTTP 、 FTP 等来存取网络数据源(服务器)的信息。客户端程序可以访问服务器获得象天气预报,股票价格、重要新闻数据,甚至是与服务器交换信息。 Internet 客户端程序可以通过外部网络( Internet )或内部网络(一般为 Intranet )访问服务器。
为了开发 Internet 客户端程序。 MFC 类库提供了专门的 Win32 Internet 扩展接口,也就是 WinInet 。 MFC 将 WinInet 封装在一个标准的、易于使用的类集合中。在编写 WinInet 客户端程序时 , 你既可以直接调用 Win32 函数,也可以使用 WinInet 类库。
Win32 Internet 扩展提供了对普通 Internet 协议的访问,这些协议包括: HTTP 、 FTP 和 Gopher 。 Gopher 已经渐渐淡出。借助于 WinInet 编程接口,开发人员不必去了解 Winsock 、 TCP/IP 和特定 Internet 协议的细节就可以编写出高水平的 Internet 客户端程序。 WinInet 为所有几种协议( HTTP 、 FTP 和 Gopher )提供了统一的函数集,也就是 Win32 API 接口。利用这些统一的函数集,大大简化了针对 HTTP 、 FTP 等协议的编程,从而轻松地将 Internet 集成到自己的应用程序中。底层协议的转换(如从 FTP 到 HTTP )只要对源代码稍作修改就可以完成。
在 Visual C++ 工程中提供有两种方式来使用 WinInet 。一种是直接调用 Win32 Internet 函数,另一种是使用 WinInet 类库。
MFC 对 WinInet 的封装是通过提供三个由 CStdioFile 派生类实现的。这三个派生类是: CInternetFile 、 CHttpFile 和 CGopherFile 。由于 Gopher 协议已经很少使用,所以本文将不再对 CGopherFile 进行讨论。对开发人员来说,不管你以前是否用过 CStdioFile , WinInet 都是很好理解并且易于使用的。它使得存取 Internet 数据易如反掌,使得 Internet 数据和本地数据的处理一致透明,数据的存储位置已经不再重要。
MFC WinInet 类有如下优点:
- 缓冲器输入输出
- 数据的类型安全处理
- 许多函数的参数都是缺省值
- 对普通的 Internet 错误进行异常处理
- 自动清除打开的句柄和连接
使用 WinInet 提供的 API 函数 , 你可以:
- 通过 HTTP 协议下载 HTML 页, HTTP 协议是专门用于在服务器和客户浏览器之间传输 HTML 页。
- 发送 FTP 请求上传或下载文件以及获取服务器的目录信息。通过匿名登陆下载文件便是 FTP 的典型应用。
- 其它基于 HTTP 、 FTP 协议的应用。
使用 WinInet 的一般流程为:
图一
下表描述了一个 Internet 客户端程序实现的一般步骤:
(表一)
实现 |
方法 |
建立一个连接 |
创建 CInternetSession 对象,它是 WinInet Internet 客户应用的前提条件 |
打开一个 URL |
建立一个连接,调用 CInternetSession::OpenURL 函数,返回一个只读资源对象 |
读取 URL 数据 |
打开一个 URL ,调用 CInternetSession::QueryOption |
查询 Internet 选项设置 |
建立一个连接,调用 CInternetFile::Read |
设置一个 Internet 选项 |
建立一个连接,调用 CInternetSession::SetOption |
设置一个用状态信息调用的函数 |
建立一个连接,调用 CInternetSession::EnableStatusCallback 重写 CInternetSession::OnStatusCallback 函数 |
关闭连接 |
用 CInternetSession 对象方法,清除打开的连接 |
为了创建 Internet 客户端程序, MFC 提供了如下的 C++ 类和全程函数:
C++ 类
CInternetSession
(父类
CObject
)
CInternetConnection (父类 CObject)
CFtpConnection
CGopherConnection
CHttpConnection
CInternetFile(父类 CStdioFile)
CGopherFile
CHttpFile
CFileFind(父类 CObject)
CFtpFileFind
CGopherFileFind
CGopherLocator(父类 CObject)
CInternetException(父类 CException)
全程函数 :
AfxParseURL
AfxGetInternetHandleType
AfxThrowInternetException
这些类和全程函数除 CFileFind 在 AFX.H 里声明之外,其余都在 AFXINET.H 文件里声明。它们对 HTTP 、 FTP 和 Gopher 等协议进行了高度抽象,形成了一套高级 API 函数。 利用这些 API 可以快速直接地开发 Internet 应用。例如,连接到 FTP 服务器一般需要几个步骤,而且需要做一些底层处理。但使用上述的 MFC 类提供的 API ,只需要对 CInternetSession::GetFTPConnection 进行一次调用,便可以轻松建立连接。
大家知道,每一个 Internet 应用其数据交换都是建立在 Internet 会话( Session )的基础之上的, MFC 是通过 CInternetSession 类对象来实现 Internet 会话的。用这个类不仅可以创建会话,而且可以创建几个并发的 Internet 会话。
为了与服务器进行通讯,除了要创建 CInternetSession 对象之外,还必须创建 CInternetConnection 对象 , 针对不同的协议, CInternetConnection 对象有三种类型:
- CInternetSession::GetFtpConnection
- CInternetSession::GetHttpConnection
- CInternetSession::GetGopherConnection
这些函数调用并不会读写服务器上的文件。如果你想要读写数据,必须要打开文件才能操作。其处理流程应该是这样的:
- 首先创建 CInternetSession 对象实例
- 如果创建的 Session 要读写文件,则必须创建 CInternetFile 对象实例(或者是它的子类 CHttpFile 、 CGopherFile 对象实例)。其实,读取数据最容易的方式是调用 CInternetSession::OpenURL 函数。 这个函数解析你提供的统一资源定位符( URL ),然后打开与 URL 指定的服务器连接,同时返回一个只读的 CInternetFile 对象。 CInternetSession::OpenURL 不针对特定的协议类型 —— 不管是 FTP 还是 HTTP 都可以调用,它甚至可以处理本地文件,此时返回的是 CStdioFile ,而不是 CInternetFile 。
- 如果创建的 Session 不读写文件,而是要实现其它的任务,如删除某个 FTP 目录下的文件等,则你不需要创建 CInternetFile 实例。
创建 CInternetFile 对象的方法有两种:
- 如果用 CInternetSession::OpenURL 建立与服务器的连接,调用返回 CStdioFile 。
- 如果用 CInternetSession::GetFtpConnection 、 GetGopherConnection 或者 CHttpConnection::OpenRequest 建立与服务器的连接,你必须调用相应的 CFtpConnection::OpenFile 、 CGopherConnection::OpenFile 或者 CHttpConnection::OpenRequest ,返回的内容也与 CInternetFile 、 CGopherFile 或者 CHttpFile 对应。
综上所述,实现 Internet 客户端应用的步骤因协议而异。要看你是创建基于 OpenURL 的一般 Internet 客户端应用,还是使用 GetXXXConnection 函数之一针对特定协议的 Internet 客户端应用。
在后继文章中我们将进一步讨论用 WinInet 实现 Internet 客户端应用程序的具体步骤和细节。(待续)