2012-11-26 4 views
1

디자인 할 계측기가 제공하는 웹 서버에 다양한 페이지가 연결되도록 보장하려고합니다. WinInet 명령을 사용하여 C++ Win32를 통해이 작업을 수행하려고합니다.WinINet을 사용하여 웹 페이지가 존재하는 경우 어떻게 찾을 수 있습니까?

은 내가 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를 표시하는 것으로 보이며 머리글 등을 실제로 이해하지 못합니다. 여기에 제가 잘못 가고있는 것 같습니다.

+0

Google "HTTP HEAD request"(** 매우 중요 ** : 해당 검색의 HTTP 부분을 포함하십시오). 나는 그것이 당신에게 힌트 또는 2를 줄지도 모른다라고 생각한다. – WhozCraig

+0

Google HEAD를 보는 것은 헤더 만 검색하는 GET의 변형입니다. 나는 그것을 함축하는 것에 가지 않고 있었지만, 단지 나를 같은 보트에두고 가지 않을 것인가? – user1853330

답변

2

HttpQueryInfo 함수는 요청과 관련된 헤더 정보를 제공하며이 경우 HTTP 상태 코드를 추출 할 수 있습니다.

더 높은 수준의 WinINet 기능을 사용하면 더 쉽게 결과를 얻을 수 있습니다. InternetOpen, InternetOpenUrl, HttpQueryInfo로 구성된 시퀀스를 제안한 다음 HTTP 상태 코드가 OK 인 경우 InternetReadFile에 대한 호출을 반복합니다.

이 델파이 코드 (델파이 7에서, 그래서 사전 유니 코드) 일을 할 것 같다 : - 그래서

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; 
+0

정보 주셔서 감사합니다. InternetOpenUrl을 사용하여 연결하려고하는데 사용자 이름과 암호를 보내야한다고 가정합니다. 분명히 헤더 또는 URL 문자열을 사용하여이 작업을 수행 할 수 있습니다. 내가 작성했습니다 :
hhttp = InternetOpenUrl (hInternet, "http : //// admin : [email protected]//home.html", NULL, 0, INTERNET_FLAG_RELOAD, 0); 핸들이나 오류를 반환하지 않습니까? – user1853330

+0

InternetOpenUrl과 사용자 이름/암호를 찾을 때 일반적으로 InternetConnect를 사용하는 것이 일반적입니다 (InternetConnect를 지정할 수 있으므로). – user1853330

0

, 나는 마침내이있어 컬과 Wireshark와의 조합을 사용하여. 근본적인 실수를 저질 렀지 만 근본적으로 바른 길로 가고 있습니다. 내가 요청을 만든 다음 보낼 필요

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); 

:

이 먼저가 ASYNC 있지 않은지 확인하고, 연결을 열고 같은 전술 한 바와 연결 (일부이 리드 IO 오류를 중복). 요청이 연결 세부 사항을 취할 때만 페이지를 지정하면됩니다.

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

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

그런 다음 HttpQueryInfo 함수를 사용하여 상태를 검색하고 다시 정수로 변환하십시오. 연결 요청이 아닌 요청에서 핸들을 전송하고 있는지 확인하십시오.그것의이 단계 간단한 다음과 같다됩니다

InternetCloseHandle(hInternet) 

감사

+0

당신이 볼 수 있듯이 나는 이미지에 접근하려고하는 것에서 내가 필요로하는 모든 것인 웹 페이지로 이동했지만 둘 다 잘 돌아갔다. – user1853330

0

: 1- 연결 열기가 3 열기 요청 3- 보내기를 연결

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

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

마지막 연결을 종료 요청 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"); 
} 
관련 문제