有什么方法可以简单地用c++发出HTTP请求吗?具体来说,我想下载一个页面(一个API)的内容,并检查内容,看看它是否包含1或0。是否也可以将内容下载到字符串中?


当前回答

以上所有的答案都是有帮助的。我的回答只是补充了一些内容:

使用boost beast,同步示例,异步示例,ssl示例 以nghttp2为例,它支持SSL、HTTP/2 使用Facebook proxygen,这个项目包括在Facebook上使用的核心c++ HTTP抽象。它的目标是高性能和并发性。我建议用vcpkg安装它,否则你会在依赖项管理上遇到困难。支持SSL。它还支持一些高级协议:HTTP/1.1、SPDY/3、SPDY/3.1、HTTP/2和HTTP/3

nghttp2和prooxygen都是稳定的,可以考虑在生产中使用。

其他回答

MS的CppRest SDK是我刚刚发现的,大约半小时后,我的第一个简单的web服务调用工作。相比之下,在这里提到的其他地方,我甚至无法安装任何东西,我不得不说,这是相当令人印象深刻的

https://github.com/microsoft/cpprestsdk

向下滚动,点击文档,然后点击入门教程,你将有一个简单的应用程序运行在任何时间。

对于这个答案,我参考了Software_Developer的答案。通过重新构建代码,我发现一些部分已弃用(gethostbyname())或不为操作提供错误处理(创建套接字,发送一些东西)。

下面的windows代码是用Visual Studio 2013和windows 8.1 64位以及windows 7 64位进行测试的。它将目标与www.google.com的Web服务器的IPv4 TCP连接。

#include <winsock2.h>
#include <WS2tcpip.h>
#include <windows.h>
#include <iostream>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
    int main (){
    // Initialize Dependencies to the Windows Socket.
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
        cout << "WSAStartup failed.\n";
        system("pause");
        return -1;
    }

    // We first prepare some "hints" for the "getaddrinfo" function
    // to tell it, that we are looking for a IPv4 TCP Connection.
    struct addrinfo hints;
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;          // We are targeting IPv4
    hints.ai_protocol = IPPROTO_TCP;    // We are targeting TCP
    hints.ai_socktype = SOCK_STREAM;    // We are targeting TCP so its SOCK_STREAM

    // Aquiring of the IPv4 address of a host using the newer
    // "getaddrinfo" function which outdated "gethostbyname".
    // It will search for IPv4 addresses using the TCP-Protocol.
    struct addrinfo* targetAdressInfo = NULL;
    DWORD getAddrRes = getaddrinfo("www.google.com", NULL, &hints, &targetAdressInfo);
    if (getAddrRes != 0 || targetAdressInfo == NULL)
    {
        cout << "Could not resolve the Host Name" << endl;
        system("pause");
        WSACleanup();
        return -1;
    }

    // Create the Socket Address Informations, using IPv4
    // We dont have to take care of sin_zero, it is only used to extend the length of SOCKADDR_IN to the size of SOCKADDR
    SOCKADDR_IN sockAddr;
    sockAddr.sin_addr = ((struct sockaddr_in*) targetAdressInfo->ai_addr)->sin_addr;    // The IPv4 Address from the Address Resolution Result
    sockAddr.sin_family = AF_INET;  // IPv4
    sockAddr.sin_port = htons(80);  // HTTP Port: 80

    // We have to free the Address-Information from getaddrinfo again
    freeaddrinfo(targetAdressInfo);

    // Creation of a socket for the communication with the Web Server,
    // using IPv4 and the TCP-Protocol
    SOCKET webSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (webSocket == INVALID_SOCKET)
    {
        cout << "Creation of the Socket Failed" << endl;
        system("pause");
        WSACleanup();
        return -1;
    }

    // Establishing a connection to the web Socket
    cout << "Connecting...\n";
    if(connect(webSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr)) != 0)
    {
        cout << "Could not connect";
        system("pause");
        closesocket(webSocket);
        WSACleanup();
        return -1;
    }
    cout << "Connected.\n";

    // Sending a HTTP-GET-Request to the Web Server
    const char* httpRequest = "GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n";
    int sentBytes = send(webSocket, httpRequest, strlen(httpRequest),0);
    if (sentBytes < strlen(httpRequest) || sentBytes == SOCKET_ERROR)
    {
        cout << "Could not send the request to the Server" << endl;
        system("pause");
        closesocket(webSocket);
        WSACleanup();
        return -1;
    }

    // Receiving and Displaying an answer from the Web Server
    char buffer[10000];
    ZeroMemory(buffer, sizeof(buffer));
    int dataLen;
    while ((dataLen = recv(webSocket, buffer, sizeof(buffer), 0) > 0))
    {
        int i = 0;
        while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
            cout << buffer[i];
            i += 1;
        }
    }

    // Cleaning up Windows Socket Dependencies
    closesocket(webSocket);
    WSACleanup();

    system("pause");
    return 0;
}

引用:

弃用gethostbyname

socket()的返回值

send()的返回值

以上所有的答案都是有帮助的。我的回答只是补充了一些内容:

使用boost beast,同步示例,异步示例,ssl示例 以nghttp2为例,它支持SSL、HTTP/2 使用Facebook proxygen,这个项目包括在Facebook上使用的核心c++ HTTP抽象。它的目标是高性能和并发性。我建议用vcpkg安装它,否则你会在依赖项管理上遇到困难。支持SSL。它还支持一些高级协议:HTTP/1.1、SPDY/3、SPDY/3.1、HTTP/2和HTTP/3

nghttp2和prooxygen都是稳定的,可以考虑在生产中使用。

HTTP协议非常简单,因此编写HTTP客户端非常简单。 这里有一个

https://github.com/pedro-vicente/lib_netsockets

它使用HTTP GET从web服务器检索文件,服务器和文件都是命令行参数。远程文件保存为本地副本。

声明:我是作者

检查http.cc https://github.com/pedro-vicente/lib_netsockets/blob/master/src/http.cc

int http_client_t::get(const char *path_remote_file)
{
  char buf_request[1024];

  //construct request message using class input parameters
  sprintf(buf_request, "GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", path_remote_file, m_server_ip.c_str());

  //send request, using built in tcp_client_t socket
  if (this->write_all(buf_request, (int)strlen(buf_request)) < 0)
  {
    return -1;
  }

编辑:编辑URL

现在正在开发一种更新的、不太成熟的卷曲包装器,称为c++ Requests。下面是一个简单的GET请求:

#include <iostream>
#include <cpr.h>

int main(int argc, char** argv) {
    auto response = cpr::Get(cpr::Url{"http://httpbin.org/get"});
    std::cout << response.text << std::endl;
}

它支持各种各样的HTTP动词和curl选项。这里有更多的使用文档。

免责声明:我是这个库的维护者。