一个Internet客户端程序的目的是通过Internet协议如:Gopher, FTP, or HTTP来存取网络数据源(服务器)的信息。一个Internet客户端程序可以访问服务器获得象天气预报,股票价格、重要新闻数据。Internet客户端程序可以通过外部网络(Internet)或内部网络(一般为Intranet)访问服务器。 MFC类库包含 Win32 Internet 扩展接口,也就是WinInet,专门用于Internet客户端程序。MFC将WinInet封装在一个标准的、易于使用的类集合中。在编写WinInet客户端程序时,你既可以直接调用win32函数,也可以使用WinInet类库。 Win32 Internet 扩展提供了对普通Internet协议的访问,这些协议包括:gopher, FTP,和 HTTP,使用WinInet可以编写出高水平的Internet客户端程序,而不必去了解winsock、TCP/IP和特定Internet协议的细节。WinInet为所有三种协议提供了统一的函数集,既Win32 API接口。如果底层协议改变(如从FTP到HTTP),利用统一的函数集,用最少的代码就可以完成改变。 Visual C++ 有两种方式来使用WinInet。一种是直接调用Win32 Internet函数,另一种是使用WinInet类库。 MFC对WinInet的封装,向类库开发人员提供熟悉的上下文。MFC提供三个由CStdioFile派生的类:CInternetFile、 CHttpFile 和 CGopherFile,对使用过CStdioFile类操作和处理本地文件的开发人员来说,这些类不仅使得获取和处理Internet数据驾轻就熟,而且使得处理本地数据和Internet数据的方式一致透明,数据的存储位置已经不重要了。 MFC WinInet 类有如下优点: 缓冲器输入输出--------Buffered I/O 安全的数据处理--------Type-safe handles for your data 众多函数带缺省参数----Default parameters for many functions 普通Internet错误的异常处理--Exception handling for common Internet errors. 自动清除打开的句柄和连接-Automatic cleanup of open handles and connections MFC 提供了下列的类和全程函数来创建Internet客户端程序。 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文件里声明。
二、方法与技巧(Tips & Knacks) | 客户端的用户要实现某些行为,必须具备先决条件(如读取文件,就必须先建立一个Internet连接)。下表以MFC为例,列出了一般的Internet URL (FTP, Gopher, or HTTP)客户端行为要实现某个目标所必须使用的方法。 | 实现 | 方法 | 建立一个连接 | 创建CInternetSession对象,它是WinInet Internet客户应用的基础 | 打开一个URL | 建立一个连接,调用CInternetSession::OpenURL 函数,返回一个只读资源对象 | 读取 URL 数据 | 打开一个URL,调用CInternetSession::QueryOption | Query Internet 选项设置 | 建立一个连接,调用CInternetFile::Read | 设置Internet选项 | 建立一个连接,调用CInternetSession::SetOption | 设置一个函数获取状态信息 | 建立一个连接,调用CInternetSession::EnableStatusCallback 重写CInternetSession::OnStatusCallback函数 |
FTP | 实现 | 方法 | 建立一个FTP连接 | 创建CInternetSession对象,它是WinInet Internet客户应用的基础。调用CInternetSession::GetFtpConnection 创建CFtpConnection对象 | Find第一个资源 | 建立一个FTP连接,创建一个CFtpFileFind对象 OpenURL函数返回一个只读资源对象 调用CFtpFileFind::FindFile | 枚举所有可获得的资源 | Find下一个资源,调用CFtpFileFind::FindNextFile 直到返回FALSE | 打开一个FTP文件 | 建立一个FTP连接,调用CFtpConnection::OpenFile 创建并打开一个CInternetFile对象 | 读取FTP文件 | 以读方式打开FTP文件,调用CInternetFile::Read | 写FTP文件 | 以写方式打开FTP文件,调用CInternetFile::Write重写CInternetSession::OnStatusCallback | 改变客户端在服务器上的目录 | 建立一个FTP连接,调用CFtpConnection::SetCurrentDirectory | 获取客户端在服务器上的当前目录 | 建立一个FTP连接,调用CFtpConnection::GetCurrentDirectory | | |
HTTP | 实现 | 方法 | 建立一个HTTP连接 | 创建CInternetSession对象,它是WinInet Internet客户应用的基础。调用CInternetSession::GetHttpConnection 创建CHttpConnection对象 | 打开一个HTTP文件 | 建立一个HTTP连接,调用CHttpConnection::OpenRequest 创建一个CHttpFile对象, 调用CHttpFile::AddRequestHeaders 调用CHttpFile::SendRequest | 读取一个HTTP文件 | 打开HTTP文件,调用CInternetFile::Read | 获取HTTP请求信息 | 建立一个HTTP连接,调用CHttpConnection::OpenRequest 创建一个CHttpFile对象 调用CHttpFile::QueryInfo |
GOPHER | 实现 | 方法 | 建立一个gopher连接 | 创建CInternetSession对象,它是WinInet Internet客户应用的基础。调用CInternetSession::GetGopherConnection 创建CGopherConnection对象 | 在当前目录中Find第一个文件 | 建立一个gopher连接, 创建一个CGopherFileFind对象, 调用CGopherConnection::CreateLocator 创建一个CGopherLocator对象, 传递locator到CGopherFileFind::FindFile. 如果需要,调用CGopherFileFind::GetLocator 获取文件的locator | 枚举所有可获得的资源 | Find下一个资源,调用CFtpFileFind::FindNextFile 直到返回FALSE | 打开一个gopher文件 | 建立一个gopher连接,调用CFtpConnection::OpenFile 调用CGopherConnection::CreateLocator创建一个 gopher locator或者用CGopherFileFind::GetLocator find一个locator 调用CGopherConnection::OpenFile. | 读取gopher文件 | 打开gopher文件,调用CInternetFile::Read 使用CGopherFile |
每一个Internet client application的基础是Internet session。MFC将Internet session作为CInternetSession类的对象来实现。使用这个类,你可以创建一个或几个并发的CInternetSession类对象。 为了与服务器通讯,你不仅需要CInternetSession对象,还需要一个CInternetConnection对象。你可以通过CInternetSession::GetFtpConnection, CInternetSession::GetHttpConnection, 或CInternetSession::GetGopherConnection 来创建相应协议的CInternetConnection对象。这些调用并不存取服务器上的文件。如果你要读写服务器上的数据,必须在另外单独的步骤中打开文件。 对于大多数Internet sessions,CInternetSession对象一般都与一个CInternetFile对象肩并肩地工作。 对于一个Internet sessions,你必须创建一个CInternetSession实例。 如果你的Internet session要读写数据,你必须创建一个CInternetFile实例,或者其子类 CHttpFile,CGopherFile的实例。读数据最容易的方式是:调用CInternetSession::OpenURL。这个函数解析你提供的URL,打开一个到URL服务器的连接,并返回一个只读的CInternetFile对象,CInternetSession::OpenURL不用指定协议类型,那种协议(FTP, HTTP, gopher)都行。CInternetSession::OpenURL甚至可以操作本地文件(返回一个CStdioFile,而不是CInternetFile)。 如果你的Internet session不读写数据,而是实现其它任务,如在一个FTP目录中删除一个文件,你可以不必创建CInternetFile实例。 有两种方式来创建CInternetFile对象: 第一种:使用CInternetSession::OpenURL建立服务器连接,这个调用返回一个 CInternetFile对象。 第二种:use CInternetSession::GetFtpConnection, GetGopherConnection, 或 GetHttpConnection建立服务器连接,你必须调用CFtpConnection::OpenFile, CGopherConnection::OpenFile, 或 CHttpConnection::OpenRequest,相应地返回 一个CInternetFile, CGopherFile, 或 CHttpFile对象, 在实现Internet client application时,你要判断是创建一个基于OpenURL的一般的Internet client,还是使用GetConnection函数之一创建一个指定协议的Internet client,根据这种判断,用不同的步骤来实现Internet client application。 下表显示了实现一个典型的Internet client application的步骤: |
目的 | 方法 | 结果 | 开始一个 Internet session | 创建一个 CInternetSession对象 | 初始化WinInet,并联接服务器 | 读或设置一个InternetQuery option (如超时或重试次数) | CInternetSession::SetOption | 不成功返回FALSE | 建立回调函数监视session状态 | 用CInternetSession::EnableStatusCallback | 建立回调函数CInternetSession::OnStatusCallback,重写OnStatusCallback,创建自己的回调例程 | Internet服务器Intranet服务器或本地文件 | 用CInternetSession::OpenURL | 解析并打开到指定服务器的连接,返回CStdioFile(如果你传递的OpenURL是本地文件名)或CInternetFile对象,通过存取这个对象,获得服务器或文件的数据 | 读文件 | 用CInternetFile::Read | 用你提供的Buffer读指定的 字节数 | 异常处理 | 用CInternetException类 | 处理所有普通的Internet 异常类型 | 结束Internet session | 处理CInternetSession对象 | 自动清除打开的句柄的连接 | 三、HTTP应用实现步骤: 下表显示了实现一个典型的HTTP client application的步骤:
目的 | 方法 | 结果 | 开始一个HTTP session | 创建一个 CInternetSession对象 | 初始化WinInet并联接服务器 | 连接到一个HTTP Server | 用CInternetSession::GetHttpConnection | 返回一个CHttpConnection对象 | 打开一个HTTP 请求 | 用CHttpConnection::OpenRequest | 返回一个CHttpFile对象 | 发送一个HTTP 请求 | 用CHttpFile::AddRequestHeaders 并且用CHttpFile::SendRequest | Find一个文件 如果文件没找到返回FALSE | 读文件 | 用CHttpFile | 使用你提供的缓冲读指定的字节 | 异常处理 | 用CInternetException类 | 处理所有普通的Internet异常类型 | 结束HTTP session | 处理CInternetSession对象 | 自动清除打开的句柄的连接 | 四、FTP应用实现步骤: 下表显示了实现一个典型的FTP client application的步骤:
目的 | 方法 | 结果 | 开始一个FTP session | 创建一个CInternetSession对象 | 初始化WinInet 并联接服务器 | 连接到一个FTP Server | 用CInternetSession::GetFtpConnection | 返回一个CFtpConnection对象 | CD到 FTP 服务器的一个新目录 | 用CFtpConnection::SetCurrentDirectory | CD到FTP服务器的一个 新目录 | Find 第一个FTP目录中的文件 | 用CFtpFileFind::FindFile | Find第一个文件,如果文件每找到返回FALSE | Find 下一个FTP目录中的文件 | 用CFtpFileFind::FindNextFile | Find下一个文件 如果文件没找到返回FALSE | 打开FindFile或FindNextFile找到的文件(用于读写) | 用CFtpConnection::OpenFile,用FindFile或FindNextFile返回的文件名 | 打开FindFile或FindNextFile找到的文件(用于读写),返回一个CInternetFile对象 | 读写文件 | 用CInternetFile::Read或CInternetFile::Write | 使用你指定的缓冲写 指定的字节数 | 异常处理 | 用CInternetException类 | 处理所有普通的Internet异常类型 | 结束FTP session | 处理CInternetSession对象 | 自动清除打开的句柄的连接 |
下表显示了实现一个典型的删除文件FTP应用的步骤:
目的 | 方法 | 结果 | 开始一个FTP session | 创建一个CInternetSession对象 | 初始化WinInet 并联接服务器 | 连接到一个FTP Server | 用CInternetSession::GetFtpConnection | 返回一个CFtpConnection对象 | Check你是在正确的FTP | 用CFtpConnection::GetCurrentDirectory或CFtpConnection::GetCurrentDirectoryAsURL | 返回目录名字 服务器目录或返回目录的URL | CD到 FTP 服务器的一个新目录 | 用CFtpConnection::SetCurrentDirectory | CD到FTP服务器的一个 新目录 | Find 第一个FTP目录中的文件 | 用CFtpFileFind::FindFile | Find第一个文件,如果文件每找到返回FALSE | Find 下一个FTP目录中的文件 | 用CFtpFileFind::FindNextFile | Find下一个文件 如果文件没找到返回FALSE | 删除FindFile或FindNextFile找到的文件 | 用CFtpConnection::Remove用FindFile或FindNextFile返回的文件名 | 删除FindFile或FindNextFile 找到的文件 | 异常处理 | 用CInternetException类 | 处理所有普通的Internet异常类型 | 结束FTP session | 处理CInternetSession对象 | 自动清除打开的句柄的连接 | |