From 3271b03bc893df27a6db3d48513fb5a78efc699b Mon Sep 17 00:00:00 2001 From: maxiaoyao Date: Thu, 26 Sep 2024 14:25:36 +0800 Subject: [PATCH] 1.add curlpp::Multi::poll/wait 2.add option:TimeoutMs 3.add example26,which use wait and TimeoutMs --- examples/README | 2 +- examples/example26.cpp | 115 +++++++++++++++++++++++++++++++++++++ include/curlpp/Multi.hpp | 6 ++ include/curlpp/Options.hpp | 1 + src/curlpp/Multi.cpp | 16 ++++++ 5 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 examples/example26.cpp diff --git a/examples/README b/examples/README index f3e8ade2..e21d231d 100644 --- a/examples/README +++ b/examples/README @@ -33,6 +33,6 @@ usage. of curlpp options. Example 24: Binded method functor for DebugFunction example. Example 25: Send e-mail over SMTP. - + Example 26: Multi interface using multi poll/wait diff --git a/examples/example26.cpp b/examples/example26.cpp new file mode 100644 index 00000000..bcf460ff --- /dev/null +++ b/examples/example26.cpp @@ -0,0 +1,115 @@ +/* +* Copyright (c) <2002-2005> +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files +* (curlpp), to deal in the Software without restriction, +* including without limitation the rights to use, copy, modify, merge, +* publish, distribute, sublicense, and/or sell copies of the Software, +* and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/** + * \file + * Multi demo using poll/wait + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +#pragma comment(lib, "Ws2_32.lib") +#endif // WIN32 + +int main(int argc, char *argv[]) { + const char *url1 = "http://www.baidu.com"; + const char *url2 = "https://cn.bing.com"; + + try { + curlpp::initialize(); + + curlpp::Easy request1; + curlpp::Easy request2; + + request1.setOpt(new curlpp::options::Url(url1)); + std::ostringstream os1; + curlpp::options::WriteStream ws1(&os1); + request1.setOpt(ws1); + + std::list headers1; + headers1.push_back("content-type:text/html; charset=utf-8"); + request1.setOpt(new curlpp::Options::HttpHeader(headers1)); + request1.setOpt(new curlpp::options::TimeoutMs(1000)); + + + request2.setOpt(new curlpp::options::Url(url2)); + std::ostringstream os2; + curlpp::options::WriteStream ws2(&os2); + request2.setOpt(ws2); + request2.setOpt(new curlpp::options::TimeoutMs(1000)); + + curlpp::Multi requests; + requests.add(&request1); + requests.add(&request2); + + /* we start some action by calling perform right away */ + int nbLeft = 0; + while (!requests.perform(&nbLeft)) { + }; + + while (nbLeft) { + // block until activity is detected on at least one of the handles or timeout_ms has passed + requests.wait(100); + while (!requests.perform(&nbLeft)) { + }; + } + + std::cout << "NB lefts: " << nbLeft << std::endl; + + /* See how the transfers went */ + /* + Multi::info returns a list of: + std::pair< curlpp::Easy, curlpp::Multi::Info > + */ + const curlpp::Multi::Msgs msgs = requests.info(); + for (auto pos = msgs.begin(); pos != msgs.end(); pos++) { + if (pos->second.msg == CURLMSG_DONE) { + /* Find out which handle this message is about */ + if (pos->first == &request1) { + std::cout << "First request completed with status " << pos->second.code << ",data:" << os1.str() << std::endl; + } else if (pos->first == &request2) { + std::cout << "Second request completed with status " << pos->second.code << ",data:" << os2.str() << std::endl; + } + } + } + + curlpp::terminate(); + + } catch (curlpp::LogicError &e) { + std::cout << e.what() << std::endl; + } catch (curlpp::RuntimeError &e) { + std::cout << e.what() << std::endl; + } + + return EXIT_SUCCESS; +} diff --git a/include/curlpp/Multi.hpp b/include/curlpp/Multi.hpp index c29102ee..3bf3e575 100644 --- a/include/curlpp/Multi.hpp +++ b/include/curlpp/Multi.hpp @@ -62,6 +62,12 @@ namespace curlpp fd_set * exc_fd_set, int * max_fd); + void wait(int timeout_ms, struct curl_waitfd extra_fds[] = nullptr, unsigned int extra_nfds = 0, int * numfds = nullptr); + +#if LIBCURL_VERSION_NUM >= 0x074200 + void poll(int timeout_ms, struct curl_waitfd extra_fds[] = nullptr, unsigned int extra_nfds = 0, int * numfds = nullptr); +#endif + typedef std::list > Msgs; diff --git a/include/curlpp/Options.hpp b/include/curlpp/Options.hpp index 40b64ed2..4d679163 100644 --- a/include/curlpp/Options.hpp +++ b/include/curlpp/Options.hpp @@ -305,6 +305,7 @@ namespace options */ typedef curlpp::OptionTrait Timeout; + typedef curlpp::OptionTrait TimeoutMs; typedef curlpp::OptionTrait LowSpeedLimit; typedef curlpp::OptionTrait LowSpeedTime; typedef curlpp::OptionTrait MaxConnects; diff --git a/src/curlpp/Multi.cpp b/src/curlpp/Multi.cpp index 58b05aad..dc97c16e 100644 --- a/src/curlpp/Multi.cpp +++ b/src/curlpp/Multi.cpp @@ -96,6 +96,22 @@ curlpp::Multi::fdset(fd_set * read, fd_set * write, fd_set * exc, int * max) } } +void curlpp::Multi::wait(int timeout_ms, struct curl_waitfd extra_fds[], unsigned int extra_nfds, int * numfds) { + CURLMcode code = curl_multi_wait(mMultiHandle, extra_fds, extra_nfds, timeout_ms, numfds); + if (code != CURLM_OK) { + throw curlpp::RuntimeError(curl_multi_strerror(code)); + } +} + +#if LIBCURL_VERSION_NUM >= 0x074200 +void curlpp::Multi::poll(int timeout_ms, struct curl_waitfd extra_fds[], unsigned int extra_nfds, int * numfds) { + CURLMcode code = curl_multi_poll(mMultiHandle, extra_fds, extra_nfds, timeout_ms, numfds); + if (code != CURLM_OK) { + throw curlpp::RuntimeError(curl_multi_strerror(code)); + } +} +#endif + curlpp::Multi::Msgs curlpp::Multi::info() {