The transfer is still set in an “easy” handle as described
above, but with the multi interface you also need a
multi CURLM *
handle created and use that to drive all the individual
transfers. The multi handle can “hold” one or many easy handles:
A multi handle can also get certain options set, which you do withcurl_multi_setopt()
, but in the simplest case you might not have anything to
set there.
To drive a multi interface transfer, you first need to add all the individual
easy handles that should be transferred to the multi handle. You can add them
to the multi handle at any point and you can remove them again whenever you
like. Removing an easy handle from a multi handle will, of course, remove the
association and that particular transfer would stop immediately.
Removing one is just as easily done:
Having added the easy handles representing the transfers you want to perform,
you write the transfer loop. With the multi interface, you do the looping so
you can ask libcurl for a set of file descriptors and a timeout value and do
the call yourself, or you can use the slightly simplified version
which does that for us, with curl_multi_wait
. The simplest loop would
basically be this: (note that a real application would check return codes)
The fourth argument to curl_multi_wait
, set to 1000 in the example above, is
a timeout in milliseconds. It is the longest time the function will wait for
any activity before it returns anyway. You don’t want to lock up for too long
before calling again as there are timeouts, progress
callbacks and more that may loose precision if you do so.
Both these loops let you use one or more file descriptors of your own on which
to wait, like if you read from your own sockets or a pipe or similar.
And again, you can add and remove easy handles to the multi handle at any
point during the looping. Removing a handle mid-transfer will, of course, abort
that transfer.
As the examples above show, a program can detect when an individual transfer
completes by seeing that the transfers_running
variable decreases.
When you do multiple parallel transfers, more than one transfer can of course
complete in the same invocation and then you might need
more than one call to curl_multi_info_read
to get info about each completed
transfer.