1

私たちが設計した楽器が提供するウェブサーバーに接続して、さまざまなページが存在することを確認しようとしています。WinInet コマンドを使用して、C++ Win32 でこれを実行しようとしています。

HTTP 経由で Web サーバーに正しく接続できてよかったです。

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 は Web サーバーを実行しているユニットのアドレスであり、galogo.png はホームページに表示されるイメージです。また、各ステートメント間でエラーをチェックしているため、イーサネットを切断するとエラーが発生することにも注意してください。

最初はhome.htmlページに接続しようとしましたが、これは常にパスしたので、画像を取得しようと思いましたが、おそらく知識が不足しています。他の例ではデータをストリーミングしているようですが、これを行う必要があるかどうかはわかりませんでした。

私が見た例のほとんどは、この形式の HtppSendRequest を示しているようで、ヘッダーなどについてよくわかりません。おそらく、ここで間違っているのでしょう。

4

3 に答える 3

2

HttpQueryInfo 関数は、リクエストに関連するヘッダー情報を提供し、これから HTTP ステータス コードを抽出できます。

より高いレベルの WinINet 関数を使用すると、より簡単に結果を得ることができる場合があります。HTTP ステータス コードが OK であれば、InternetOpen、InternetOpenUrl、HttpQueryInfo、および 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;
于 2012-11-26T15:43:52.703 に答える
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 関数を使用してステータスを取得し、整数に変換します。Connect ではなく Request からハンドルを送信していることを確認してください。

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

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

最後に接続をシャットダウンします。

InternetCloseHandle(hInternet)

ありがとう

于 2012-11-27T09:37:02.277 に答える