How do you make a HTTP request with C++?

后端 未结 22 2921
有刺的猬
有刺的猬 2020-11-22 06:25

Is there any way to easily make a HTTP request with C++? Specifically, I want to download the contents of a page (an API) and check the contents to see if it contains a 1 o

22条回答
  •  情书的邮戳
    2020-11-22 06:49

    With this answer I refer to the answer from Software_Developer. By rebuilding the code I found that some parts are deprecated (gethostbyname()) or do not provide error handling (creation of sockets, sending something) for an operation.

    The following windows code is tested with Visual Studio 2013 and Windows 8.1 64-bit as well as Windows 7 64-bit. It will target an IPv4 TCP Connection with the Web Server of www.google.com.

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

    References:

    Deprecation of gethostbyname

    Return Value of socket()

    Return Value of send()

提交回复
热议问题