一、WinInet API 简介
WinInet (Win32 Internet Extensions) API是 Windows 提供的编写 Internet 客户端程序的专用接口。这些接口提供了对普通 Internet 协议的访问:HTTP、FTP、Gopher。
二、WinInet API 结构图(部分)
三、主要函数介绍
1. InternetOpen
初始化WinInet。函数原型如下:
HINTERNET InternetOpen(
LPCTSTR lpszAgent, //指定调用 WinINet 函数的应用程序或入口,该入口用作HTTP协议中用户代理项
DWORDdw AccessType, //访问要求类型
LPCTSTR lpszProxyName, //当lAccessType类型为INTERNET_OPEN_TYPE_PROXY时,指定代理服务器的名字。
LPCTSTR lpszProxyBypass, //指定一个可选的主机名列表或IP地址,列表可包括未知元素。
DWORD dwFlags //标记
);
2. InternetOpenUrl
通过一个完整的HTTP、FTP或Gopher网址打开一个资源。函数原型如下:
HINTERNET InternetOpenUrl(
HINTERNET hInternet, //当前的 Internet 会话句柄。句柄必须由前面的 InternetOpen 调用返回
LPCTSTR lpszUrl, //指定读取的网址。只有以http:, ftp:, gopher:或者 https: 开头的网址被支持。
LPCTSTR lpszHeaders, //指定发送到HTTP服务器的头信息
DWORD dwHeadersLength, //额外的头信息的大小,以TCHAR为单位
DWORD dwFlags, //标记
DWORD_PTR dwContext //指向一个应用程序定义的值,将随着返回的句柄,一起传递给回调函数
);
3. InternetConnect
为指定的站点打开一个HTTP、FTP或Gopher会话。函数原型如下:
HINTERNET InternetConnect(
HINTERNET hInternet, //当前的 Internet 会话句柄。句柄必须由前面的 InternetOpen 调用返回
LPCTSTR lpszServerName, //指定一个Internet服务器的主机名称
INTERNET_PORT nServerPort, //指定要连接的端口号
LPCTSTR lpszUsername, //指定登录用户名
LPCTSTR lpszPassword, //指定登录密码
DWORD dwService, //指定要访问的服务类型
DWORD dwFlags, //标记
DWORD_PTR dwContext //指向一个应用程序定义的值,将随着返回的句柄,一起传递给回调函数
);
4.HttpOpenRequest
创建一个HTTP请求句柄。函数原型如下:
HINTERNET HttpOpenRequest(
HINTERNET hConnect, //InternetConnect返回的HTTP会话句柄
LPCTSTR lpszVerb, //指定HTTP访问方式,如:GET、POST
LPCTSTR lpszObjectName, //指定的HTTP动作的目标对象名称
LPCTSTR lpszVersion, //指定HTTP版本号
LPCTSTR lpszReferer, //指定引用页
LPCTSTR *lpszAcceptTypes, //指定客户端接收的媒体类型
DWORD dwFlags, //标记
DWORD_PTR dwContext //指向一个应用程序定义的值,将随着返回的句柄,一起传递给回调函数
);
5. HttpSendRequest
发送指定的HTTP请求到服务器。函数原型如下:
BOOL HttpSendRequest(
HINTERNET hRequest, //HttpOpenRequest返回的HTTP请求句柄
LPCTSTR lpszHeaders, //指定额外的头信息
DWORD dwHeadersLength, //额外的头信息长度
LPVOID lpOptional, //指定要发送给服务器的附加数据
DWORD dwOptionalLength //附加数据长度
);
6. InternetReadFile
接收数据。函数原型如下:
BOOL InternetReadFile(
HINTERNET hFile, //由InternetOpenUrl、HttpOpenRequest、FtpOpenFile返回的有效句柄
LPVOID lpBuffer, //指定接收数据的缓冲区
DWORD dwNumberOfBytesToRead, //指定要接收的数据长度
LPDWORD lpdwNumberOfBytesRead //实际接收的数据长度
);
四、应用实例(HTTP)(Visual C++ 2010编译运行通过)
1. 直接使用 InternetOpenUrl 函数
DWORD CNetTestDlg::GetHtml(void)
{
HINTERNET hInternet=InternetOpen(_T("NetTest"),INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
if(!hInternet)
throw "Failed to initialize network.";
HINTERNET hUrl=InternetOpenUrl(hInternet,_T("http://www.google.com"),NULL,0,INTERNET_FLAG_RELOAD,0);
if(!hUrl)
throw "Failed to open the specified url.";
char szBuffer[16384];
memset(szBuffer,0,16384);
DWORD dwRead=0;
BOOL bSuccess=InternetReadFile(hUrl,szBuffer,16384,&dwRead);
if(!bSuccess)
throw "Failed to receive data.";
int len=MultiByteToWideChar(CP_ACP,0,szBuffer,-1,NULL,0);
wchar_t *pwStr=new wchar_t[len];
MultiByteToWideChar(CP_ACP,0,szBuffer,-1,pwStr,len);
SetDlgItemText(IDC_EDIT_READ,pwStr);
InternetCloseHandle(hUrl);
InternetCloseHandle(hInternet);
return dwRead;
}
2. 使用 InternetConnect、HttpOpenRequest和 HttpSendRequest
DWORD CNetTestDlg::GetHtml(void)
{
HINTERNET hInternet=InternetOpen(_T("NetTest"),INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
if(!hInternet)
throw "Failed to initialize network.";
HINTERNET hConnection=InternetConnect(hInternet,_T("www.baidu.com"),INTERNET_INVALID_PORT_NUMBER,NULL,NULL,INTERNET_SERVICE_HTTP,0,0);
if(!hConnection)
throw "Failed to connect the host.";
HINTERNET hRequest=HttpOpenRequest(hConnection,_T("GET"),_T("index.html"),_T("HTTP/1.1"),NULL,NULL,INTERNET_FLAG_RELOAD,0);
if(!hRequest)
throw "Failed to open the request.";
BOOL bSuccess=HttpSendRequest(hRequest,NULL,0,NULL,0);
if(!bSuccess)
throw "Failed to send the request.";
char szBuffer[16384];
memset(szBuffer,0,16384);
DWORD dwRead=0;
BOOL bRead=InternetReadFile(hRequest,szBuffer,16384,&dwRead);
if(!bRead)
throw "Failed to receive date.";
int len=MultiByteToWideChar(CP_ACP,0,szBuffer,-1,NULL,0);
wchar_t *pwstr=new wchar_t[len];
MultiByteToWideChar(CP_ACP,0,szBuffer,-1,pwstr,len);
SetDlgItemText(IDC_EDIT_READ,pwstr);
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnection);
InternetCloseHandle(hInternet);
}
运行结果: