C ++中套接字的HTTP请求

时间:2013-07-16 19:35:21

标签: c++ sockets http

我对C ++套接字(Linux)创建的HTTP请求有一个问题。我需要从API获取一些信息。

#include <iostream>
#include <ctype.h>
#include <cstring>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sstream>
#include <fstream>
#include <string>

using namespace std;

int sock;
struct sockaddr_in client;
int PORT = 80;

int main(int argc, char const *argv[])
{
    struct hostent * host = gethostbyname("api.themoviedb.org");

    if ( (host == NULL) || (host->h_addr == NULL) ) {
        cout << "Error retrieving DNS information." << endl;
        exit(1);
    }

    bzero(&client, sizeof(client));
    client.sin_family = AF_INET;
    client.sin_port = htons( PORT );
    memcpy(&client.sin_addr, host->h_addr, host->h_length);

    sock = socket(AF_INET, SOCK_STREAM, 0);

    if (sock < 0) {
        cout << "Error creating socket." << endl;
        exit(1);
    }

    if ( connect(sock, (struct sockaddr *)&client, sizeof(client)) < 0 ) {
        close(sock);
        cout << "Could not connect" << endl;
        exit(1);
    }

    stringstream ss;
    ss << "GET /3/movie/" << 550 << "?api_key=xxx HTTP/1.1\r\n"
       << "Host: api.themoviedb.org\r\n"
       << "Accept: application/json\r\n"
       << "\r\n\r\n";
    string request = ss.str();

    if (send(sock, request.c_str(), request.length(), 0) != (int)request.length()) {
        cout << "Error sending request." << endl;
        exit(1);
    }

    char cur;
    while ( read(sock, &cur, 1) > 0 ) {
        cout << cur;
    }

    return 0;
}

但问题是它需要太长时间。它开始写入对控制台的响应,但它在9/10结束,之后大约需要30秒才能结束。当我试图改变循环时:

cout << cur;

要:

cout << cur << endl;

然后它写了一个完整的结果,但在它之后程序滞后了一段时间。这段代码有什么问题?当我尝试通过终端的经典卷曲得到回应一切都很好。谢谢你的帮助

2 个答案:

答案 0 :(得分:4)

Web服务器可能正在等待您的下一个HTTP请求打开连接,这将永远不会到来。服务器最终超时并关闭连接。您可以通过以下任一方式更改此行为:

  1. 请求服务器使用请求中的Connection: close标题行关闭连接

  2. 解析响应标头,以便在响应结束后知道何时停止读取。有关如何检测响应结束的规则,请参阅RFC 2616 Section 4.4

答案 1 :(得分:1)

您可以在请求中使用HTTP / 1.0作为版本,因为1.0版本确定服务器应在每次请求后关闭连接。