2009-07-14 48 views
11

在Win32中是否沒有用於本地C/C++的「高級」HTTP庫?或者我只是在錯誤的位置查找? 「高級」我的意思是一個API,它允許我在C++中執行HTTP Web請求/響應,並且與.NET框架具有「大致相同」的抽象級別(但請注意,使用C++/CLI不是一種選擇爲了我)。用於Win32中的本地C/C++的高級HTTP客戶端庫

如何在不使用.NET的情況下在Win32的C/C++中做這樣的事情(使用大致相同的代碼量)?作爲參考,我包含一個代碼示例以顯示如何在C#中執行此操作。

byte[] fileBytes = null; 
bool successfulDownload = false; 
using (WebClient client = new WebClient()) 
{ 
    WebProxy proxy = WebProxy.GetDefaultProxy(); 
    client.Proxy = proxy; 
tryAgain: 
    try 
    { 
     fileBytes = client.DownloadData(fileUrl); 
     successfulDownload = true; 
    } 
    catch (WebException wEx) 
    { 
     if (wEx.Response != null && wEx.Response is HttpWebResponse) 
     { 
      string username = null, password = null; 
      bool userCanceled = false; 
      HttpStatusCode statusCode = ((HttpWebResponse)wEx.Response).StatusCode; 
      switch (statusCode) 
      { 
       case HttpStatusCode.ProxyAuthenticationRequired: 
        // This is just a convenience function defined elsewhere 
        GetAuthenticationCredentials(fileUrl, true, 
         out username, out password, out userCanceled); 
        if (!userCanceled) 
        { 
         client.Proxy.Credentials = new NetworkCredential(username, password); 
         goto tryAgain; 
        } 
        break; 
       case HttpStatusCode.Unauthorized: 
        // This is just a convenience function defined elsewhere 
        GetAuthenticationCredentials(fileUrl, false, 
         out username, out password, out userCanceled); 
        if (!userCanceled) 
        { 
         client.Credentials = new NetworkCredential(username, password); 
         goto tryAgain; 
        } 
        break; 
      } 
     } 
    } 
} 
+0

重複:http://stackoverflow.com/questions/822581/what-c​​-library-for-http-client – 2009-07-14 08:43:50

回答

8

Win32提供了Internet*函數。

http://msdn.microsoft.com/en-us/library/aa385473(VS.85).aspx

你需要做的(IIRC,我還沒有在超過10年的感動這些API)InternetOpenURLInternetReadFile

+0

這和我打算做的事情一樣接近,但還不夠。問題在於您需要爲「異國情調」的代理方案(自動代理配置腳本和Web代理自動發現協議)編寫相當多的代碼。 – 2009-07-14 09:32:20

7

我認爲libcurl符合那些要求。然後還有一些。

This example顯示如何獲取HTTP頁面,僅將其存儲在內存中。這是比你的例子多一點的代碼,但它在C.

+0

這是一個很好的答案 - libcurl確實是一個偉大的庫,而我目前使用的是。然而,它在代理領域不足。例如,它不支持(如.NET類)自動代理配置腳本。 – 2009-07-14 09:30:59

1

你是不是看錯了地方。這只是悲傷的現實。這就是爲什麼libcurl叫做curlpp的C++包裝器。

以下是關於如何檢索網頁並將其打印到標準輸出流的example

#include <curlpp/curlpp.hpp> 
#include <curlpp/Easy.hpp> 
#include <curlpp/Options.hpp> 


using namespace curlpp::options; 

int main(int, char **) 
{ 
    try 
    { 
    // That's all that is needed to do cleanup of used resources (RAII style). 
    curlpp::Cleanup myCleanup; 

    // Our request to be sent. 
    curlpp::Easy myRequest; 

    // Set the URL. 
    myRequest.setOpt<Url>("http://example.com"); 

    // Send request and get a result. 
    // By default the result goes to standard output. 
    myRequest.perform(); 
    } 

    catch(curlpp::RuntimeError & e) 
    { 
    std::cout << e.what() << std::endl; 
    } 

    catch(curlpp::LogicError & e) 
    { 
    std::cout << e.what() << std::endl; 
    } 

    return 0; 
} 
4

POCO也有跨平臺的網絡組件。

實例得到FTP程序作爲這樣的(這是不帶錯誤檢查絨毛)

Poco::Net::FTPStreamFactory::registerFactory(); 
std::ofstream localFile(inputFile, std::ios_base::out | std::ios_base::binary); 
Poco::URI uri(inputURL); 
std::auto_ptr<std::istream> ptrFtpStream(Poco::Net::URIStreamOpener::defaultOpener().open(uri)); 
Poco::StreamCopier::copyStream(*ptrFtpStream.get(), localFile); 
1

Qt庫QtNetwork的一部分,也是一種可能性。

7

除了libcurl/curlpp(這是靈活的和強大的,但我覺得非常...笨重),有兩個C++庫我正在關注。兩者都很新,基於Boost :: ASIO。然而都不支持支持代理服務器(盡我所知)。 (blog)可能更成熟(我知道它有一些真實世界的測試),但目前缺乏超時(我正在努力!)。例如:

network::http::request request("http://google.com"); 
network::http::client client; 
network::http::response response; 

response = client.get(request); 
if (response.status() == 200) 
{ 
    std::cout << body(response)); 
} 

Urdldocumentation)由ASIO創作者寫的,有超時(但只公佈上個月)。它採用了不同的模型,選擇加入與流工作:

urdl::istream is("http://google.com"); 
std::string line; 
while (std::getline(is, line)) 
{ 
    std::cout << line << std::endl; 
} 

我同意C++沒有爲HTTP,但是這兩個庫顯示了很多的承諾大力支持。