一般而言,开发Internet服务客户端程序的目的是通过Internet协议(HTTP,FTP)获取网络数据源的信息,微软提供了专门的Win32 Internet扩展接口,也就是WinInet。
1使用Win API函数开发客户端程序
一般流程是,首先通过InternetOpen()函数创建位于根部的HINTERNET句柄,然后才能进一步建立HTTP、FTP会话,使用InternetConnect()函数创建一个指定的会话,初始化HTTP、FTP会话(根据指定的参数决定),并创建一个根句柄的分支,HttpOpenRequest()、FtpOpenFile()、FtpFindFirstFile()等函数将使用InternetConnect()所创建的句柄,建立到指定站点的连接。例子代码如下:
bool testFtpDownload ()
{
// 建立会话
HINTERNET hInternet;
hInternet = InternetOpen("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hInternet == NULL) return false;
// 建立连接
HINTERNET hConnect;
hConnect = InternetConnect(hInternet, "112.128.125.11", INTERNET_INVALID_PORT_NUMBER,
"", "", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
if(hInternet == NULL) { InternetCloseHandle(hInternet); return false; }
HINTERNET hFtpFile;
hFtpFile = FtpOpenFile(hConnect, "common/ Essential C++中文版.pdf", GENERIC_READ, FTP_TRANSFER_TYPE_BINARY|INTERNET_FLAG_RELOAD, NULL);
if(hFtpFile == NULL) { InternetCloseHandle(hConnect); InternetCloseHandle(hInternet); return false; }
char buf[1024];
DWORD buf_len = 1024;
DWORD buf_read = 1024;
FILE *fp = fopen("e:\\test.pdf", "wb");
while(1)
{
InternetReadFile(hFtpFile, buf, buf_len, &buf_read);
if(buf_read == 0) break;
fwrite(buf, 1, buf_read, fp);
}
fclose(fp);
InternetCloseHandle(hFtpFile);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return true;
}
bool testHttpDownload()
{
// 建立会话
HINTERNET hInternet;
hInternet = InternetOpen("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hInternet == NULL) return false;
// 建立连接
HINTERNET hConnect;
hConnect = InternetConnect(hInternet, "hi.baidu.com", INTERNET_INVALID_PORT_NUMBER,
"", "", INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
if(hInternet == NULL) { InternetCloseHandle(hInternet); return false; }
HINTERNET httpFile;
httpFile = HttpOpenRequest(hConnect, "GET", "vc_net/blog/item/2d830208fe388bc063d986b2.html", HTTP_VERSION, NULL, 0, INTERNET_FLAG_NO_UI | INTERNET_FLAG_DONT_CACHE, 1);
if(httpFile == NULL) { InternetCloseHandle(hConnect); InternetCloseHandle(hInternet); return false; }
HttpSendRequest(httpFile, NULL, NULL, 0, 0);
char buf[1024];
DWORD buf_len = 1024;
DWORD buf_read = 1024;
FILE *fp = fopen("e:\\test.txt", "wb");
while(1)
{
InternetReadFile(httpFile, buf, buf_len, &buf_read);
if(buf_read == 0) break;
fwrite(buf, 1, buf_read, fp);
}
fclose(fp);
InternetCloseHandle(httpFile);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return true;
}
2.使用mfc类开发客户端程序
网络客户端开发的要点是Internet Session,而mfc将Internet Session作为CInternetSession类的对象来实现,需要包含头文件#include <afxinet.h>
大多数Internet Session都需要与服务器进行读写数据的操作,这就需要CInternetSession对象与一个CInternetFile对象的协同工作,即必须创建一个CInternetFile实例或者其子类CHttpFile的对象。创建CInternetFile对象有两种方法:
1)直接调用CInternetSession::OpenURL函数,该函数打开一个到URL的连接,并返回一个只读的CInternetFile对象.它还可以操作本地文件(由URL资源“file://”标志),但是返回一个CStdioFile对象。
2)调用相应服务协议类的打开函数
通过CInternetSession::GetHttpConnection, CInternetSession::GetFtpConnection建立的服务器连接对话,则必须调用CHttpConnection::OpenRequest,CFtpConnection::OpenFile函数,返回一个CHttpFile、CFtpFile对象。
2.1使用WinInet访问HTTP服务器
最简单的方法是创建CInternetSession对象,以HTTP站点的URL参数调用OpenURL(),返回一个CInternetFile文件句柄,以此句柄操作文件。例如代码如下:
bool DownloadHtml(const string& url, const string& filename)
{
char buf[1000];
FILE* fp = fopen(filename.c_str(),"wb");
if (NULL == fp)
return false;
DWORD nRead = 0;
CInternetSession localsession;
CInternetFile* webfile = NULL;
try
{
webfile = (CInternetFile*)localsession.OpenURL(url.c_str());
}
catch(CInternetException* pException)
{
webfile = NULL;
pException->Delete();
}
while((nRead = webfile->Read(buf,1000)) > 0)
fwrite(buf, 1, nRead, fp);
fclose(fp);
delete webfile;
localsession.Close();
return true;
}
2.2使用WinInet访问FTP服务器
常使用CFtpConnection类,具体方法如下:
调用函数CInternetSession::GetFtpConnection()建立连接,该函数所需的参数依次为FTP站点域名、用户名、密码、FTP服务端口号(缺省为21)、访问模式(被动或主动)。
连接建立完成后,用CFtpConnection类的方法操作远程FTP服务器的文件系统,具体如下:
SetCurrentDirectory(GetCurrentDirectory)设置(获取)此连接的FTP目录。
RemoveDirectory(CreateDirectory)删除(创建)目录
Rename、Remove、PutFile、GetFile、OpenFile等对文件进行更名、删除、上传、下载及打开等操作。
用Close函数关闭与FTP服务器的连接。
例子代码如下:
bool DownloadFile(const string& url, const string& filename)
{
CInternetSession localsession(L"my session");
CFtpConnection* ftp= localsession.GetFtpConnection(L"122.118.125.11",L"",L"",21);
// ftp->GetFile(L"test/信息.txt",L"e:\\tt.txt");
ftp->PutFile(L"e:\\tjl.txt",L"common/test.txt");
ftp->Close();
localsession.Close();
return true;
}