一般而言,開發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;
}