2013-08-16 18 views
0

我想在C++中使用WinHTTP獲取網頁的內容。 這是有點工作,除了我能夠查看部分源而不是整個源。C++ WinHTTP InternetReadFile不檢索整個源碼

OpenSSL的東西在那裏,因爲最終我希望能夠通過SSL做HTTP,但這是下一個挑戰。

#include <windows.h> 
#include <Wininet.h> 

#pragma comment(lib, "Crypt32.lib") 
#pragma comment(lib, "wininet.lib") 


bool SetupSSL(HINTERNET request) 
{ 
    HCERTSTORE store = CertOpenSystemStore(NULL,"CA"); 
    DWORD ret = 0; 
    bool ok = false; 

    if(store==NULL)  
     return false; 
    PCCERT_CONTEXT context = CertFindCertificateInStore(store,X509_ASN_ENCODING,0,CERT_FIND_SUBJECT_STR,L"WebClient",NULL); 
    if(context!=NULL) 
    {    
     ok = InternetSetOption(request,INTERNET_OPTION_CLIENT_CERT_CONTEXT,(LPVOID)context,sizeof(CERT_CONTEXT))==TRUE; 
     if(!ok)   
      ret = GetLastError(); 
     CertFreeCertificateContext(context); 
    } 
    MessageBoxA(0, "1", 0, 0); 
    CertCloseStore(store,0); 
    return ok; 
}; 


int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) 
{ 
    HINTERNET hint = InternetOpen("WebTestClient",INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0); 
    if(hint!=NULL) 
    { 
     //InternetSetStatusCallback(hint,&HTTPStatusCallbackFunc); 
     HINTERNET hsession = InternetConnect(hint,"encrypted.google.com",443,NULL,NULL,3,0,NULL); 

     if(hsession!=NULL) 
     { 
      HINTERNET hreqest = HttpOpenRequest(hsession,"GET","/","HTTP/1.1",NULL,NULL,INTERNET_FLAG_SECURE|INTERNET_FLAG_NO_AUTH,NULL); 
      if(hreqest!=NULL) 
      { 
       //if(SetupSSL(hreqest)) 
       //{ 

        if(HttpSendRequest(hreqest,NULL,0, NULL, 0)) 
        {     
         //char szResponse[1024] = ""; 
         char szBuffer[1024] = ""; 
         DWORD dwRead=0;     


         while(InternetReadFile(hreqest, szBuffer, sizeof(szBuffer)-1, &dwRead) && dwRead) 
         { 
          //strcat(szBuffer, szResponse); 
          szBuffer[dwRead] = 0; 
          OutputDebugStringA(szBuffer);    
          dwRead=0;      
         }          

         //InternetReadFile(hreqest, szBuffer, sizeof(szBuffer)-1, &dwRead); 
         MessageBoxA(0, szBuffer, 0, 0); // Only shows the first part of the source. 
        }    

       //} 
       //else 
       //{ 
        //MessageBoxA(0, "SetupSSL failed", 0, 0); 
       //} 
       InternetCloseHandle(hreqest); 
      }  
      InternetCloseHandle(hsession); 
     }  
     InternetCloseHandle(hint); 
    } 

    return 0; 
} 

OutPutDebugStringA正在將整個源輸出到調試控制檯,因此它已準備就緒。只是不把它全部存儲在szBuffer變量中。我認爲這可能與循環有關。

+0

您是否在循環中抱怨您自己的覆蓋'szBuffer',以便您可以在調試輸出中看到完整的內容,並且只能看到消息框的最後一部分? –

+0

即使我註釋掉szBuffer [dwRead] = 0;我仍然只能使用MessageBox – SnakeByte

回答

0

while(InternetReadFile(hreqest, szBuffer, sizeof(szBuffer)-1, ...

您繼續使用InternetReadFile到同一個緩衝區szBuffer覆蓋您已經有存在的東西讀。

通常你會希望有一個靈活的/重新分配此緩衝區,或緩衝區的列表,只是這裏的代碼簡潔,這裏是你能做的順序讀取到足夠大的固定大小的緩衝區的內容:

static const SIZE_T g_nBufferCapacity = 128 * 1024; // 128 KB 
CHAR szBuffer[nBufferCapacity] = ""; 
SIZE_T nBufferSize = 0; 

szBuffer[0] = 0; 
for(; ;) 
{ 
    DWORD nReadableSize = min(1024, sizeof(szBuffer) - nBufferSize - 1); 
    DWORD nReadSize = 0; 
    InternetReadFile(hreqest, szBuffer + nBufferSize, nReadableSize, &nReadSize); // TODO: Error Checking 
    if(!nReadSize) 
    break; 
    szBuffer[nBufferSize + nReadSize] = 0; 
    OutputDebugStringA(szBuffer + nBufferSize);    
    nBufferSize += nReadSize; 
}          
+0

工作查看部分源代碼。感謝羅馬。 – SnakeByte

+0

@Roman - 使用後需要刪除dzBuffer嗎? –

+0

@TheofanisPantelides:在這段代碼中,緩衝區位於堆棧中,因此不需要刪除。 –