2014-02-18 1 views
0

Я использую CURL-библиотеки с C++, чтобы получить очень большой JSON-строку из этого URL: (. Это приблизительно длиной 170 000 символов) https://www.bitstamp.net/api/order_book/?group=1Curl дело с большим JSON-ответ

Моя проблема что cURL не передает всю строку моей функции обратного вызова. Я тестировал его со стандартной функцией обратного вызова и печатал всю строку в stdout, поэтому я могу с уверенностью сказать, что это не проблема с получением данных. Но как только вызывается моя функция обратного вызова, переданные данные имеют размер как точно 7793, так и 15776 символов. (Я не могу думать о каких-либо изменений, которые могли бы correllate с изменением этих 2-х номеров)

я первая мысль значение CURL_MAX_WRITE_SIZE может быть причиной так я изменил его от 16384 до 131072, но это не помогло:

#ifdef CURL_MAX_WRITE_SIZE 
    #undef CURL_MAX_WRITE_SIZE 
    #define CURL_MAX_WRITE_SIZE 131072 
#endif 

это краткий обзор моего кода:

class EXCHANGE 
{ 
    public: 

    enum { BASE_TYPE }; //to check if template-types are derived from this class 

    virtual size_t orderbookDataProcessing(void* buffer, unsigned int size, unsigned int nmemb) = 0; 

    template <typename TTYPE> //only for classes derived from EXCHANGE 
    static size_t orderbookDataCallback(void* buffer, unsigned int size, unsigned int nmemb, void* userdata) 
    { 
     //check if TTYPE is derived from EXCHANGE (BASE_TYPE is declared in EXCHANGE) 
     enum { IsItDerived = TTYPE::BASE_TYPE }; 

     TTYPE* instance = (TTYPE*)userdata; 

     if(0 != instance->orderbookDataProcessing(buffer, size, nmemb)) 
     { 
      return 1; 
     } 
     else 
     { 
      return (size*nmemb); 
     } 
    } 
} 

class BITSTAMP : public EXCHANGE 
{ 
    public: 

    size_t orderbookDataProcessing(void* buffer, unsigned int size, unsigned int nmemb) 
    { 
     string recvd_string; //contains the received string 

     //copy the received data into a new string 
     recvd_string.append((const char*)buffer, size*nmemb); 

     //do stuff with the recvd_string 

     return 0; 
    } 
} 


//main.cpp 
/////////////////////////////////// 

CURL* orderbook_curl_handle = curl_easy_init(); 

curl_easy_setopt(orderbook_curl_handle, CURLOPT_URL, "https://www.bitstamp.net/api/order_book/?group=1") //URL to receive the get-request 

curl_easy_setopt(orderbook_curl_handle, CURLOPT_HTTPGET, 1) //use get method 

curl_easy_setopt(orderbook_curl_handle, CURLOPT_NOSIGNAL, 1) //required for multi-threading ? 

curl_easy_setopt(orderbook_curl_handle, CURLOPT_WRITEDATA, &bitstamp_USD) //instance passed to the callback-function 

curl_easy_setopt(orderbook_curl_handle, CURLOPT_WRITEFUNCTION, (size_t(*)(void*, unsigned int, unsigned int, void*))&EXCHANGE::orderbookDataCallback<BITSTAMP>) //callback function to recv the data 

curl_easy_setopt(orderbook_curl_handle, CURLOPT_SSL_VERIFYPEER, FALSE) //do not verify ca-certificate 

curl_easy_perform(orderbook_curl_handle); 

ответ

3

CURL вызывает ваш обратный вызов записи с данными, как он получает. Если ваши данные слишком велики (и у вас есть), они будут переданы вам через несколько вызовов обратного вызова записи.

Вам нужно будет собрать данные из каждого обратного вызова записи, пока CURL не сообщит вам, что ответ завершен. В вашем случае это должно быть, когда возвращается curl_easy_perform.

+0

В библиотеке, подобной [json-c] (https://github.com/json-c/json-c), вы можете выполнить прогрессивный разбор JSON: вот [конкретный пример с libcurl] (https: // github.com/deltheil/json-url). – deltheil