简体   繁体   English

无法接收HTTP响应正文C ++

[英]Unable to receive HTTP response body C++

First, here is the C++ code I am using to make HTTP POST requests. 首先,这是我用来发出HTTP POST请求的C ++代码。 It links to ws2_32.lib . 它链接到ws2_32.lib

int POST_TEST(std::string URL, std::string DATA)
{
    //**************************************************

    std::string TEXT        = "";
    std::string DIRECTORY   = URL.substr(URL.find(".com") + std::string(".com").length());
    std::string HOST        = URL.substr(0, URL.find(".com", std::string(".com").length())) + ".com";
    std::string REQ         = "POST " + DIRECTORY + " HTTP/1.1\r\nContent-Length: " + to_string(DATA.length()) + "\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nHost: " + HOST + "\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nUser-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:44.0) Gecko/20100101 Firefox/44.0\r\nConnection: keep-alive\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n" + DATA;
    const char * REQUEST    = REQ.c_str();

    //**************************************************

    WSADATA wsaData;

    if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        return 1;

    SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    struct hostent *host = gethostbyname(HOST.c_str());

    SOCKADDR_IN SockAddr;
    SockAddr.sin_port = htons(80);
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);

    if(connect(Socket,(SOCKADDR*)(&SockAddr), sizeof(SockAddr)) != 0)
        return 1;

    send(Socket, REQUEST, strlen(REQUEST), 0);

    char buffer[1000];
    int nDataLength;

    while((nDataLength = recv(Socket, buffer, 1000, 0)) > 0)
    {
        int i = 0;

        while(buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r')
        {
            TEXT += buffer[i];
            i++;
        }
    }

    closesocket(Socket);
    WSACleanup();

    MessageBoxA(NULL, TEXT.c_str(), "HTTP Response", MB_OK);

    return 0;
}

POST_TEST("blah.com/a.php", "a=blah");

The code works well, but I am receiving only the HTTP Header response, and I don't see the response BODY. 该代码运行良好,但是我只收到HTTP Header响应,而我没有看到响应BODY。 Making the POST request using Python to the same php page allows me to see the response body just fine. 使用Python向同一php页面发出POST请求,使我看到响应主体就好了。 I'm not sure if I'm misunderstanding something, or there's an error in my code. 我不确定是否误解了某些内容,或者我的代码中有错误。

The PHP page I'm POSTing to is located on my own server. 我要发布到的PHP页面位于我自己的服务器上。 The PHP echoes some text, but I do not see that in the response. PHP回显了一些文本,但是我在响应中看不到该文本。 This is the response I get: 这是我得到的答复:

HTTP/1.1 200 OK
Server: nginx/1.8.1
Date: Fri, 08 Apr 2016 02:10:14 GMT
Content-Type: text/html
Content-Length: 286
Connection: keep-alive
Vary: Accept-Encoding
Content-Encoding: gzip

How would I be able to see the entire response? 我将如何看到整个回复?

There are two bugs in the shown code. 所示代码中有两个错误。

  • It doesn't check the return value from send() . 它不检查send()的返回值。 send() does not guarantee that the number of bytes requested to be sent was actually sent. send()不保证请求发送的字节数确实已发送。 The return value from send() may return an indication that fewer bytes were written than what were requested. send()的返回值可能会返回指示,表明写入的字节数少于请求的字节数。 It is your responsibility to check that, and try again to send() the remaining bytes. 您有责任进行检查,然后再次尝试send()剩余字节。

  • The logic for reading and collecting the response is wrong. 读取和收集响应的逻辑是错误的。 recv() tells you how many bytes were received. recv()告诉您接收了多少字节。 This is ignored completely. 这完全被忽略。 Instead, the code scans the read buffer until it sees a control character as a byte. 相反,代码将扫描读取缓冲区,直到将控制字符视为一个字节为止。

Note that your HTTP response indicates that you're getting raw, gzip-compressed binary data. 请注意,您的HTTP响应表明您正在获取原始的,gzip压缩的二进制数据。 It is fairly likely that within the first few bytes of the actual response there are going to be some binary bytes that correspond to ASCII control characters, in value. 在实际响应的前几个字节中,很可能会有一些二进制字节,它们的值与ASCII控制字符相对应。 Your loop will come to a screeching halt at that point. 此时,您的循环将停止运转。

Even if you were expecting a plain text response, this logic would still be wrong. 即使您期望纯文本响应,此逻辑仍然是错误的。 It is the return value from recv() that tells you how many bytes were received, and nothing else. 它是来自recv()的返回值,它告诉您接收了多少个字节,没有别的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM