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

时间:2016-04-08 02:03:23

标签: c++ http post http-headers httpresponse

首先,这是我用来发出HTTP POST请求的C ++代码。它链接到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");

代码运行良好,但我只收到HTTP Header响应,我没有看到响应BODY。使用Python将POST请求发送到同一个php页面允许我看到响应正文。我不确定我是否误解了某些内容,或者我的代码中存在错误。

我正在发布的PHP页面位于我自己的服务器上。 PHP回应了一些文本,但我没有在响应中看到它。这是我得到的回应:

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

我怎样才能看到整个回复?

1 个答案:

答案 0 :(得分:3)

显示的代码中有两个错误。

  • 它不会检查send()的返回值。 send()不保证实际发送请求发送的字节数。来自send()的返回值可能返回指示写入的字节数少于请求的字节数。您有责任检查,然后再次尝试send()剩余的字节。

  • 阅读和收集回复的逻辑是错误的。 recv()告诉您收到了多少字节。这完全被忽略了。相反,代码会扫描读缓冲区,直到它将控制字符视为一个字节。

请注意,您的HTTP响应表明您正在获取原始的gzip压缩二进制数据。很可能在实际响应的前几个字节内,将会有一些二进制字节与值对应的ASCII控制字符。你的循环将在那时突然停止。

即使您期望明文回复,这种逻辑仍然是错误的。它是来自recv()的返回值,它告诉您接收了多少字节,而不是其他任何字节。