Win32中用于本机C / C ++的高级HTTP客户端库

时间:2009-07-14 08:15:16

标签: c++ http winapi client

在Win32中是否没有用于本机C / C ++的“高级”HTTP库,或者我只是在错误的地方寻找?

“高级”是指一种API,它允许我使用与.NET框架“大致相同”的抽象级别在C ++中执行HTTP Web请求/响应(但请注意,使用C ++ / CLI不是一个选项我)。

如何在不使用.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;
            }
        }
    }
}

7 个答案:

答案 0 :(得分:8)

Win32提供Internet*个功能。

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

您需要做一个(IIRC,我在10年内没有触及这些API)InternetOpenURLInternetReadFile

答案 1 :(得分:7)

我认为libcurl符合这些要求。然后是一些。

This example显示了如何获取HTTP页面,仅将其存储在内存中。这是比你的例子更多的代码,但它在C中。

答案 2 :(得分:7)

除了libcurl / curlpp(灵活且功能强大,但我觉得非常......笨重)之外,还有两个我正在关注的C ++库。两者都是全新的,基于Boost :: ASIO。但是既没有支持代理(我能说的最好)。

cpp-netlibblog)可能更成熟(我知道它有一些真实的测试),但目前缺少超时(我正在研究它!)。例如:

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没有很好的支持,但这两个库都显示出很多希望。

答案 3 :(得分: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);

答案 4 :(得分:1)

在错误的地方寻找。那只是悲伤的现实。这就是为什么libcurl的c ++包装器叫curlpp

以下是example如何检索网页并将其打印到stdout流。{/ p>

#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;
}

答案 5 :(得分:1)

Qt库的一部分,QtNetwork,也是一种可能性。

答案 6 :(得分:0)