如何使用WinINet查找是否存在网页

时间:2012-11-26 12:33:31

标签: c++ get wininet

我正在尝试连接并确保我们设计的工具提供的网络服务器上存在各种页面。我试图通过使用WinInet命令的C ++ Win32来做到这一点。

我很高兴我通过HTTP正确连接到网络服务器:

hInternet = InternetOpen("Test", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0/*INTERNET_FLAG_ASYNC*/);
hhttp = InternetConnect(hInternet, "192.168.111.222", INTERNET_DEFAULT_HTTP_PORT, "admin", "admin", INTERNET_SERVICE_HTTP, 0, 0);

我相信我必须打开一个请求。

hHttpRequest = HttpOpenRequest(hhttp, "GET", "galogo.png", NULL, "192.168.111.222", lplpszAcceptTypes, INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE, 0);

然后发送请求。

HttpSendRequest(hHttpRequest, NULL, 0, NULL, 0)

注意:192.168.111.222是运行网络服务器的设备的地址,galogo.png是主页上显示的图像。还请注意我在每个语句之间进行错误检查,所以如果我断开以太网,那么我确实会失败。

最初我确实尝试过连接到home.html页面,但这总是通过,所以我认为我应该尝试获取图像,但我可能缺乏知识。其他例子似乎然后流数据,但我不确定我是否需要这样做。

我见过的大多数示例似乎都以这种格式显示了HtppSendRequest,我并不真正理解标题等。也许它就在这里我出错了。

3 个答案:

答案 0 :(得分:2)

HttpQueryInfo函数将提供与请求相关的标头信息,您可以从中提取HTTP状态代码。

您可以使用更高级别的WinINet功能更轻松地实现结果。我会建议一个由InternetOpen,InternetOpenUrl,HttpQueryInfo组成的序列,然后如果HTTP状态代码没问题,则重复调用InternetReadFile。

这个Delphi代码(来自Delphi 7,所以在Unicode之前)似乎可以完成这项工作: -

function GetUrlContent(const Agent, Url: string): string;
var
  NetHandle: HINTERNET;
  UrlHandle: HINTERNET;
  Buffer: array [0..1024] of Char;
  BytesRead: DWORD;
  Dummy: DWORD;
  BufLen: DWORD;
  HttpStatus: string;
begin
  Result := '';
  NetHandle := InternetOpen(PChar(Agent), INTERNET_OPEN_TYPE_PRECONFIG,
    nil, nil, 0);

  if Assigned(NetHandle) then
  begin
    UrlHandle := InternetOpenUrl(NetHandle, PChar(Url), nil, 0,
      INTERNET_FLAG_RELOAD, 0);

    if Assigned(UrlHandle) then
    // UrlHandle valid?  Proceed with download.
    try
      BufLen := Length(Buffer);
      Dummy := 0;
      // only get the file if the HTTP status code is 200
      if HttpQueryInfo(UrlHandle, HTTP_QUERY_STATUS_CODE, @Buffer[0], BufLen, Dummy) then
      begin
        HttpStatus := Buffer;
        if HttpStatus = '200' then
        begin
          FillChar(Buffer, SizeOf(Buffer), 0);
          repeat
            Result := Result + Buffer;
            FillChar(Buffer, SizeOf(Buffer), 0);
            InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead);
          until BytesRead = 0;
        end
        else begin
          raise Exception.CreateFmt('HTTP status code %s', [HttpStatus]);
        end;
      end
      else begin
        raise Exception.Create('Unable to read HTTP status code');
      end;
    finally
      InternetCloseHandle(UrlHandle);
    end
    else begin
      // UrlHandle is not valid.  Raise an exception.
      raise Exception.CreateFmt('Cannot open URL %s', [Url]);
    end;
    InternetCloseHandle(NetHandle);
  end
  else begin
    // NetHandle is not valid.  Raise an exception.
    raise Exception.Create('Unable to initialize WinINet');
  end;
end;

答案 1 :(得分:0)

所以,使用cURL和Wireshark的组合,我终于到了。我犯了一些基本的错误,但基本上是在正确的轨道上。

首先打开连接并按照前面的说明连接,确保它不是ASYNC(这会导致一些重叠的IO错误):

hInternet = InternetOpen("Test", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0/*INTERNET_FLAG_ASYNC*/);

hhttp = InternetConnect(hInternet, "192.168.111.222", INTERNET_DEFAULT_HTTP_PORT, "admin", "admin", INTERNET_SERVICE_HTTP, 0, 0);

我需要创建请求然后发送它。我只需要指定页面,因为请求将采用连接细节。

hHttpRequest = HttpOpenRequest(hhttp, "GET", "home.html", NULL, NULL, lplpszAcceptTypes, INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE, 0);

HttpSendRequest(hHttpRequest, NULL, 0, NULL, 0);

然后使用HttpQueryInfo函数检索状态并转换回整数。确保您从请求而不是连接发送句柄。

//These are defined earlier
DWORD statCharLen = 0;
char statChar[256]="";    
statCharLen = sizeof(statChar);

HttpQueryInfo(hHttpRequest, HTTP_QUERY_STATUS_CODE, statChar, &statCharLen, NULL);

最后关闭连接:

InternetCloseHandle(hInternet)

由于

答案 2 :(得分:0)

以下是步骤: 1-打开连接 2-连接 3-打开请求 4-发送请求 5-读取文件 6-保存文件(如png或jpg) 7-关闭手柄 代码如下:

#include <iostream>
#include <string>
#include <Windows.h>
#include <wininet.h>
#pragma comment(lib, "wininet")

using namespace std;
void download(string domain,string url,string filepath)
{
    //Step 1:
    HINTERNET hIntSession = InternetOpenA("MyApp", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    //Step 2:
    HINTERNET hHttpSession = InternetConnectA(hIntSession, domain.c_str(), 80, 0, 0, INTERNET_SERVICE_HTTP, 0, NULL);
    //Step 3:
    HINTERNET hHttpRequest = HttpOpenRequestA( hHttpSession, "GET",url.c_str(),0, 0, 0, INTERNET_FLAG_RELOAD, 0);
    TCHAR* szHeaders = L"";
    CHAR szReq[1024] = "";
    //Step 4:
    if( !HttpSendRequest(hHttpRequest, szHeaders, wcslen(szHeaders), szReq, strlen(szReq))) {
        DWORD dwErr = GetLastError();
        cout<<"error "<<dwErr<<endl;
        /// handle error
    }
    TCHAR szBuffer[1025];
    DWORD dwRead=0;
    FILE *f;
    f=fopen(filepath.c_str(),"wb");
    //Step 5 & 6:
    while(InternetReadFile(hHttpRequest,szBuffer, 1024, &dwRead) && dwRead)
    {
        fwrite(szBuffer,sizeof(BYTE),1024,f);
        dwRead=0;
    }
    fclose(f);
    //Step 7:
    InternetCloseHandle(hHttpRequest);
    InternetCloseHandle(hHttpSession);
    InternetCloseHandle(hIntSession);
}
int main()
{
    download("www.stacktoheap.com","images/stackoverflow.png","C:\\Example\\example.png");
}