0

C++ ソケット (Linux) によって作成された HTTP 要求に問題が 1 つあります。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;

次に、完全な結果を書き込みますが、その後、プログラムはしばらく遅れます。このコードの何が問題になっていますか? ターミナルからクラシックカールで応答を取得しようとすると、すべて問題ありませんでした。ご協力いただきありがとうございます

4

2 に答える 2

4

Web サーバーはおそらく、次の HTTP 要求を待機するために接続を開いたままにしていますが、それは決して来ません。サーバーは最終的にタイムアウトになり、接続を閉じます。この動作は、次のいずれかで変更できます。

  1. Connection: closeリクエストのヘッダー行を使用してサーバーに接続を閉じるように要求する

  2. 応答ヘッダーを解析して、応答の終わりを取得したらいつ読み取りを停止するかを知る。応答の終わりを検出する方法の規則については、RFC 2616 セクション 4.4を参照してください。

于 2013-07-16T19:48:01.050 に答える