在C++中使用Windows API发送HTTP GET请求

摘要:
在网上找了很多文章,但基本都是说,C++发送HTTP请求可以,但谈到具体方法,就众说众说纷纭了。具体说来,有IXMLHTTPRequest2、curl、POCO,当然还有用socket、WindowsAPI的方法。最后我使用了WindowsAPI,用的头文件,配合使用winhttp.lib库,成功,而且感觉,只需封装一下,这是我想要的方法://CppConsole.cpp:定义控制台应用程序的入口点。

在网上找了很多文章,但基本都是说,C++发送HTTP请求可以,但谈到具体方法,就众说众说纷纭了。具体说来,有IXMLHTTPRequest2、curl、POCO,当然还有用socket、Windows API的方法。这些方法中,除了socket外,我都尝试过。

首先我用的是curl,需要先编译,编译完成后,就可以用curl_xxx的函数来发送和接收请求了,但是马上我就发现了一个问题,必须使用动态链接库才能运行,即使我编译好了静态库,还指定了/MT(而不是/MD),也不行。非常的尴尬,本来应该是一个跨平台的完美解决方案,但就因为这样一个愚蠢的原因,就没探索了。

然后我尝试使用COM组件,需要用到<MsXml6.h>头文件和<MsXml6.lib>库,网上有IXMLHTTPRequest2的例子,但例子是Windows Store上的应用,语法也是C++/CX,部分代码还用到了.NET里面的东西(虽然我相信可以不需要.NET),移植了一阵子后,感觉很麻烦,就换方法了。

再然后我发现POCO库可以解决这个问题,当准备用POCO库的时候,发现也需要编译,就想到了以前编译curl和gmp后的结果(静态库总有这样或那样的问题,动态库正常),然后直接没信心再试了。

最后我使用了Windows API,用的<winhttp.h>头文件,配合使用winhttp.lib库,成功,而且感觉,只需封装一下,这是我想要的方法:

//CppConsole.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"#include <winhttp.h>
#pragma comment(lib, "winhttp")

using namespacestd;

voiddo_work();

int _tmain(int argc, _TCHAR*argv[])
{
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF |_CRTDBG_LEAK_CHECK_DF );
    do_work();
}

voiddo_work()
{
    DWORD dwSize = 0;
    DWORD dwDownloaded = 0;
    LPSTR pszOutBuffer;
    BOOL bResults =FALSE;
    HINTERNET hSession =NULL, 
              hConnect =NULL, 
              hRequest =NULL;

    //Use WinHttpOpen to obtain a session handle.
    hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", 
                           WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 
                           WINHTTP_NO_PROXY_NAME, 
                           WINHTTP_NO_PROXY_BYPASS, 0);

    //Specify an HTTP server
    if(hSession)
        hConnect = WinHttpConnect(hSession, L"baidu.com", 
                                  INTERNET_DEFAULT_HTTP_PORT, 0);

    //Create an HTTP Request handle.
    if(hConnect)
        hRequest = WinHttpOpenRequest(hConnect, L"GET", 
                                      L"", 
                                      NULL, WINHTTP_NO_REFERER, 
                                      WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                      0);

    //Send a Request.
    if(hRequest)
        bResults =WinHttpSendRequest(hRequest, 
                                      WINHTTP_NO_ADDITIONAL_HEADERS, 
                                      0, WINHTTP_NO_REQUEST_DATA, 0, 
                                      0, 0);

    //End the request.
    if(bResults)
        bResults =WinHttpReceiveResponse(hRequest, NULL);

    //Continue to verify data until there is nothing left.
    if(bResults)
    {
        do{
            //Verify available data.
            dwSize = 0;
            if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
                printf("Error %u in WinHttpQueryDataAvailable.\n", 
                       GetLastError());
            
            //Allocate space for the buffer.
            pszOutBuffer = new char[dwSize+1];
            
            //Read the Data.
            ZeroMemory(pszOutBuffer, dwSize+1);

            if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, 
                                 dwSize, &dwDownloaded))
                printf("Error %u in WinHttpReadData.\n", GetLastError());
            elseprintf("%s\n", pszOutBuffer);

            //Free the memory allocated to the buffer.
delete[] pszOutBuffer;
        } while (dwSize > 0);
    } 

    //Report errors.
    if (!bResults)
        printf("Error %d has occurred.\n", GetLastError());

    //Close open handles.
    if(hRequest) WinHttpCloseHandle(hRequest);
    if(hConnect) WinHttpCloseHandle(hConnect);
    if(hSession) WinHttpCloseHandle(hSession);
}
View Code

免责声明:文章转载自《在C++中使用Windows API发送HTTP GET请求》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇base64的编码解码的一些坑Qt布局下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

转载 Android之网络与通信

2.三种网络接口简述2.1标准Java接口java.net.*提供与联网有关的类,包括流和数据包套接字、Internet协议、常见HTTP处理。使用java.net.*包连接网络代码:Java代码 收藏代码try{ //定义地址 URL url=newURL("http://www.google.com"); //打开连接 HttpURLConn...

URLConnection的连接、超时、关闭用法总结

Java中可以使用HttpURLConnection来请求WEB资源。 1、URL请求的类别 分为二类,GET与POST请求。二者的区别在于:a:) get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,b:) post与get的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。 2、URLConn...

HTTP数据包头解析(简单清楚)

[转]HTTP请求模型和头信息参考 参考: http://blog.csdn.net/baggio785/archive/2006/04/13/661410.aspx模型: http://blog.csdn.net/baggio785/archive/2006/04/13/661412.aspx   HTTP请求模型 一、连接至Web服务器一个客户端应用(...

在HTTP通讯过程中,是客户端还是服务端主动断开连接?

比如说:IE访问IIS,获取文件,肯定是要建立一个连接,这个连接在完成通讯后,是客户端Close了连接,还是服务端Close了连接。我用程序测模拟IE和IIS,都没有收到断开连接的消息,也就是都没有触发OnClose事件。我是用Socket建立的连接。如果两方面都没有主动断开连接,那么我猜测可能是传输的数据中有结束的标志,请问这个标志是怎样的?谢谢各位。...

haproxy 配置详解

OPTION 选项: option httpclose :HAProxy会针对客户端的第一条请求的返回添加cookie并返回给客户端,客户端发送后续请求时会发送                              此cookie到HAProxy,HAProxy会针对此cookie分发到上次处理此请求的服务器上,如果服务器不能忽略           ...

http实现发送post请求,获取结果集

1 package com.ming; 2 3 import java.io.BufferedReader; 4 import java.io.InputStreamReader; 5 import java.io.OutputStreamWriter; 6 import java.io.PrintWriter; 7 impor...