Как обработать несколько ответов от сервера curl c++

Есть некоторый сервер, к которому я подключаюсь при помощи curl и далее этот сервер отправляет некоторые ответы, которые я должен получать и выводить. У меня имеется следующий код, который по идее должен выполнять вышеописанные функции:

void listen(CURL* curl)
{
    char buf[1024];
    size_t num;
    curl_easy_recv(curl, buf, sizeof buf, &num);
    std::cout << buf;
}

int main()
{
    CURL* curl = curl_easy_init();
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_perform(curl);
    
    while (true)
        listen(curl);
}

Но этот код выводит только первый ответ, получаемый от сервера и всё, больше ничего не происходит, даже когда от сервера поступают другие ответы, ничего не выводится на консоль, хотя должно. Подскажите, что я делаю не так и как это исправить?


Ответы (1 шт):

Автор решения: S.H.

Как я понимаю, в main'е Вы инициализируете curl и в цикле вызываете функцию, котрая запрашивает стриницу по URL.

При этом url остаётся одним и тем же.

По сути, в цике Вы спрашиваете у сервера одну и ту же страницу.

Именно поэтому у Вас в цикле выводится одно и то же.

Но сервера могут быть устроены весьма хитро. Например, если обращаться к url-у "случайный анекдот" какого нибудь анекдот.ру - то при каждом обращении у вас будет другой анекдот.

Но в большинстве случаев, по одному и тому же url сервер отдаёт одно и то же содержимое.

И не зная, какой URL вы запрашиваете - не могу заранее сказать, что нужно сделать, чтобы перейти к следующей "порции данных".

Навскидку - может помочь модификация url на каждом шаге цикла.

Например, вот такая последовательность url откроет последовательно несколько страниц списка статей хабра:

https://habr.com/ru/all/

https://habr.com/ru/all/page2/

https://habr.com/ru/all/page3/

Ваша задача - при запросе с произвольного сайта - осложняется еще и тем, что многие сайты строят страницу на стороне клиента. То есть, в браузер загружается некий минимальный js-код, который начинает потом делать запросы к серверу, и менять содержимое страницы. curl такого не умеет - это "тупая качалка".

Дополнение насчет longpool

longpool - очень хороший пример не стандартного протокола. Протокол основан на том, что клиент коннектится к серверу... и висит. Сервер ему ничего не отвечает. А вот в тот момент, когда возникла какая то информация, которую надо передать клиенту - сервер "выплёвывает" её в уже созданное со стороны клиенту подключение и завершает сессию.

Клиент, получив порцию информации - немедленно переконнекчивается. И опять висит.

Тонкостьв том, что сервер при подключении анализирует заголовки клиента, и в некоторых случаях может "оутлупнуть" его просто по значению client agent. Проверить просто: нужно запустить соедиение из браузера и посмотерть его через fiddler и потом попробовать то же самое через программу, использующую curl. Если при этом сессия сильно отличается - значит, подделывать заголовки надо лучше :-)

Вот очень хорошая статья по поводу лонгпула, и пусть Вас не смущет то, что она про питончик - для c++ изменения будут, но основа там изложена верно.

Если статья не помогла решить проблему - напишите, пожалуйста, конкретный URL, который надо попробовать "полонгпулить" - я могу попробовать это сделать как нибудь вечерком.

Надеюсь, мой ответ Вам был полезен.

→ Ссылка