在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;
}
}
}
}
答案 0 :(得分:8)
Win32提供Internet*
个功能。
http://msdn.microsoft.com/en-us/library/aa385473(VS.85).aspx
您需要做一个(IIRC,我在10年内没有触及这些API)InternetOpenURL
和InternetReadFile
。
答案 1 :(得分:7)
我认为libcurl符合这些要求。然后是一些。
This example显示了如何获取HTTP页面,仅将其存储在内存中。这是比你的例子更多的代码,但它在C中。
答案 2 :(得分:7)
除了libcurl / curlpp(灵活且功能强大,但我觉得非常......笨重)之外,还有两个我正在关注的C ++库。两者都是全新的,基于Boost :: ASIO。但是既没有支持代理(我能说的最好)。
cpp-netlib(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));
}
Urdl(documentation)由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)