libcurl docs: improvements all over
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
.\" *
|
.\" *
|
||||||
.\" * This software is licensed as described in the file COPYING, which
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * you should have received as part of this distribution. The terms
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
.\" * KIND, either express or implied.
|
.\" * KIND, either express or implied.
|
||||||
.\" *
|
.\" *
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.TH curl_easy_duphandle 3 "18 September 2001" "libcurl 7.9" "libcurl Manual"
|
.TH curl_easy_duphandle 3 "19 Sep 2014" "libcurl" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_easy_duphandle - Clone a libcurl session handle
|
curl_easy_duphandle - Clone a libcurl session handle
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -47,5 +47,4 @@ in a synchronous way, the input handle may not be in use when cloned.
|
|||||||
If this function returns NULL, something went wrong and no valid handle was
|
If this function returns NULL, something went wrong and no valid handle was
|
||||||
returned.
|
returned.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_global_init "(3)
|
.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_global_init "(3)"
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
.\" *
|
.\" *
|
||||||
.\" * This software is licensed as described in the file COPYING, which
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * you should have received as part of this distribution. The terms
|
||||||
@@ -39,5 +39,6 @@ This function was added in libcurl 7.12.1
|
|||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Nothing
|
Nothing
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_easy_setopt "(3)
|
.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_easy_setopt "(3),"
|
||||||
|
.BR curl_easy_duphandle "(3)"
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
.\" *
|
.\" *
|
||||||
.\" * This software is licensed as described in the file COPYING, which
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * you should have received as part of this distribution. The terms
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
.\" * KIND, either express or implied.
|
.\" * KIND, either express or implied.
|
||||||
.\" *
|
.\" *
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.TH libcurl 3 "12 Aug 2003" "libcurl 7.10.7" "libcurl easy interface"
|
.TH libcurl 3 "19 Sep 2014" "libcurl" "libcurl easy interface"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libcurl-easy \- easy interface overview
|
libcurl-easy \- easy interface overview
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
@@ -33,6 +33,17 @@ without a specified URL as you may have figured out yourself). You might want
|
|||||||
to set some callbacks as well that will be called from the library when data
|
to set some callbacks as well that will be called from the library when data
|
||||||
is available etc. \fIcurl_easy_setopt(3)\fP is used for all this.
|
is available etc. \fIcurl_easy_setopt(3)\fP is used for all this.
|
||||||
|
|
||||||
|
\fICURLOPT_URL(3)\fP is only option you really must set, as otherwise there
|
||||||
|
can be no transfer. Another commonly used option is \fICURLOPT_VERBOSE(3)\fP
|
||||||
|
that will help you see what libcurl is doing under the hood, very useful when
|
||||||
|
debugging for example. The \fIcurl_easy_setopt(3)\fP man page has a full index
|
||||||
|
of the over 200 available options.
|
||||||
|
|
||||||
|
If you at any point would like to blank all previously set options for a
|
||||||
|
single easy handle, you can call \fIcurl_easy_reset(3)\fP and you can also
|
||||||
|
make a clone of an easy handle (with all its set options) using
|
||||||
|
\fIcurl_easy_duphandle(3)\fP.
|
||||||
|
|
||||||
When all is setup, you tell libcurl to perform the transfer using
|
When all is setup, you tell libcurl to perform the transfer using
|
||||||
\fIcurl_easy_perform(3)\fP. It will then do the entire operation and won't
|
\fIcurl_easy_perform(3)\fP. It will then do the entire operation and won't
|
||||||
return until it is done (successfully or not).
|
return until it is done (successfully or not).
|
||||||
@@ -42,4 +53,5 @@ transfer, or if you're done, cleanup the session by calling
|
|||||||
\fIcurl_easy_cleanup(3)\fP. If you want persistent connections, you don't
|
\fIcurl_easy_cleanup(3)\fP. If you want persistent connections, you don't
|
||||||
cleanup immediately, but instead run ahead and perform other transfers using
|
cleanup immediately, but instead run ahead and perform other transfers using
|
||||||
the same easy handle.
|
the same easy handle.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_easy_setopt "(3)"
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
.\" *
|
.\" *
|
||||||
.\" * This software is licensed as described in the file COPYING, which
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * you should have received as part of this distribution. The terms
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
.\" *
|
.\" *
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH libcurl-multi 3 "3 Feb 2007" "libcurl 7.16.0" "libcurl multi interface"
|
.TH libcurl-multi 3 "19 Sep 2014" "libcurl" "libcurl multi interface"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libcurl-multi \- how to use the multi interface
|
libcurl-multi \- how to use the multi interface
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
@@ -43,18 +43,28 @@ complicated for the application.
|
|||||||
|
|
||||||
3. Enable the application to wait for action on its own file descriptors and
|
3. Enable the application to wait for action on its own file descriptors and
|
||||||
curl's file descriptors simultaneous easily.
|
curl's file descriptors simultaneous easily.
|
||||||
|
|
||||||
|
4. Enable event-based handling and scaling transfers up to and beyond
|
||||||
|
thousands of parallel connections.
|
||||||
.SH "ONE MULTI HANDLE MANY EASY HANDLES"
|
.SH "ONE MULTI HANDLE MANY EASY HANDLES"
|
||||||
To use the multi interface, you must first create a 'multi handle' with
|
To use the multi interface, you must first create a 'multi handle' with
|
||||||
\fIcurl_multi_init(3)\fP. This handle is then used as input to all further
|
\fIcurl_multi_init(3)\fP. This handle is then used as input to all further
|
||||||
curl_multi_* functions.
|
curl_multi_* functions.
|
||||||
|
|
||||||
Each single transfer is built up with an easy handle. You must create them,
|
With a multi handle and the multi interface you can do any amount of
|
||||||
and setup the appropriate options for each easy handle, as outlined in the
|
simultaneous transfers in parallel. Each single transfer is built up around an
|
||||||
\fIlibcurl(3)\fP man page, using \fIcurl_easy_setopt(3)\fP.
|
easy handle. You must create the easy handles you need, and setup the
|
||||||
|
appropriate options for each easy handle, as outlined in the \fIlibcurl(3)\fP
|
||||||
|
man page, using \fIcurl_easy_setopt(3)\fP.
|
||||||
|
|
||||||
When the easy handle is setup for a transfer, then instead of using
|
There are two flavours of the multi interface, the select() oriented one and
|
||||||
\fIcurl_easy_perform(3)\fP (as when using the easy interface for transfers),
|
the event based one we called multi_socket. You will benefit from reading
|
||||||
you should instead add the easy handle to the multi handle using
|
through the description of both versions to full understand how they work and
|
||||||
|
differentiate. We start out with the select() oriented version.
|
||||||
|
|
||||||
|
When an easy handle is setup for a transfer, then instead of using
|
||||||
|
\fIcurl_easy_perform(3)\fP like when using the easy interface for transfers,
|
||||||
|
you should add the easy handle to the multi handle with
|
||||||
\fIcurl_multi_add_handle(3)\fP. The multi handle is sometimes referred to as a
|
\fIcurl_multi_add_handle(3)\fP. The multi handle is sometimes referred to as a
|
||||||
\'multi stack\' because of the fact that it may hold a large amount of easy
|
\'multi stack\' because of the fact that it may hold a large amount of easy
|
||||||
handles.
|
handles.
|
||||||
@@ -71,7 +81,8 @@ application drive. You drive the transfers by invoking
|
|||||||
anything available to transfer. It'll use the callbacks and everything else
|
anything available to transfer. It'll use the callbacks and everything else
|
||||||
you have setup in the individual easy handles. It'll transfer data on all
|
you have setup in the individual easy handles. It'll transfer data on all
|
||||||
current transfers in the multi stack that are ready to transfer anything. It
|
current transfers in the multi stack that are ready to transfer anything. It
|
||||||
may be all, it may be none.
|
may be all, it may be none. When there's nothing more to do for now, it
|
||||||
|
returns back to the calling application.
|
||||||
|
|
||||||
Your application can acquire knowledge from libcurl when it would like to get
|
Your application can acquire knowledge from libcurl when it would like to get
|
||||||
invoked to transfer data, so that you don't have to busy-loop and call that
|
invoked to transfer data, so that you don't have to busy-loop and call that
|
||||||
@@ -80,7 +91,9 @@ interface using which you can extract fd_sets from libcurl to use in select()
|
|||||||
or poll() calls in order to get to know when the transfers in the multi stack
|
or poll() calls in order to get to know when the transfers in the multi stack
|
||||||
might need attention. This also makes it very easy for your program to wait
|
might need attention. This also makes it very easy for your program to wait
|
||||||
for input on your own private file descriptors at the same time or perhaps
|
for input on your own private file descriptors at the same time or perhaps
|
||||||
timeout every now and then, should you want that.
|
timeout every now and then, should you want that. \fIcurl_multi_timeout(3)\fP
|
||||||
|
also helps you with providing a suitable timeout period for your select()
|
||||||
|
call.
|
||||||
|
|
||||||
\fIcurl_multi_perform(3)\fP stores the number of still running transfers in
|
\fIcurl_multi_perform(3)\fP stores the number of still running transfers in
|
||||||
one of its input arguments, and by reading that you can figure out when all
|
one of its input arguments, and by reading that you can figure out when all
|
||||||
@@ -121,21 +134,39 @@ using large numbers of simultaneous connections.
|
|||||||
When using this API, you add easy handles to the multi handle just as with the
|
When using this API, you add easy handles to the multi handle just as with the
|
||||||
normal multi interface. Then you also set two callbacks with the
|
normal multi interface. Then you also set two callbacks with the
|
||||||
CURLMOPT_SOCKETFUNCTION and CURLMOPT_TIMERFUNCTION options to
|
CURLMOPT_SOCKETFUNCTION and CURLMOPT_TIMERFUNCTION options to
|
||||||
\fIcurl_multi_setopt(3)\fP.
|
\fIcurl_multi_setopt(3)\fP. They are two callback functions that libcurl will
|
||||||
|
call with information about what sockets to wait for, and for what activity,
|
||||||
|
and what the curret timeout time is - if that expires libcurl should be
|
||||||
|
notified.
|
||||||
|
|
||||||
The API is then designed to inform your application about which sockets
|
The multi_socket API is designed to inform your application about which
|
||||||
libcurl is currently using and for what activities (read and/or write) on
|
sockets libcurl is currently using and for what activities (read and/or write)
|
||||||
those sockets your application is expected to wait for.
|
on those sockets your application is expected to wait for.
|
||||||
|
|
||||||
Your application must then make sure to receive all sockets informed about in
|
Your application must make sure to receive all sockets informed about in the
|
||||||
the CURLMOPT_SOCKETFUNCTION callback and make sure it reacts on the given
|
CURLMOPT_SOCKETFUNCTION callback and make sure it reacts on the given activity
|
||||||
activity on them. When a socket has the given activity, you call
|
on them. When a socket has the given activity, you call
|
||||||
\fIcurl_multi_socket_action(3)\fP specifying which socket and action there
|
\fIcurl_multi_socket_action(3)\fP specifying which socket and action there
|
||||||
are.
|
are.
|
||||||
|
|
||||||
The CURLMOPT_TIMERFUNCTION callback is called to set a timeout. When that
|
The CURLMOPT_TIMERFUNCTION callback is called to set a timeout. When that
|
||||||
timeout expires, your application should call the
|
timeout expires, your application should call the
|
||||||
\fIcurl_multi_socket_action(3)\fP function saying it was due to a timeout.
|
\fIcurl_multi_socket_action(3)\fP function saying it was due to a timeout.
|
||||||
|
|
||||||
|
This API is typically used with an event-driven underlying functionality (like
|
||||||
|
libevent, libev, kqueue, epoll or similar) which which the application
|
||||||
|
"subscribes" on socket changes. This allows applications and libcurl to much
|
||||||
|
better scale upward and beyond thousands of simultaneous transfers without
|
||||||
|
losing performance.
|
||||||
|
|
||||||
|
When you've added your initial set of handles, you call
|
||||||
|
\fIcurl_multi_socket_action(3)\fP with CURL_SOCKET_TIMEOUT set in the sockfd
|
||||||
|
argument, and you'll get callbacks call that sets you up and you then continue
|
||||||
|
to call \fIcurl_multi_socket_action(3)\fP accordingly when you get activity on
|
||||||
|
the sockets you've been asked to wait on, or if the timeout timer expires.
|
||||||
|
|
||||||
|
You can poll \fIcurl_multi_info_read(3)\fP to see if any transfer has
|
||||||
|
completed, as it then has a message saying so.
|
||||||
.SH "BLOCKING"
|
.SH "BLOCKING"
|
||||||
A few areas in the code are still using blocking code, even when used from the
|
A few areas in the code are still using blocking code, even when used from the
|
||||||
multi interface. While we certainly want and intend for these to get fixed in
|
multi interface. While we certainly want and intend for these to get fixed in
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
.\" *
|
.\" *
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH libcurl-tutorial 3 "2 Aug 2014" "libcurl" "libcurl programming"
|
.TH libcurl-tutorial 3 "19 Sep 2014" "libcurl" "libcurl programming"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libcurl-tutorial \- libcurl programming tutorial
|
libcurl-tutorial \- libcurl programming tutorial
|
||||||
.SH "Objective"
|
.SH "Objective"
|
||||||
@@ -137,15 +137,17 @@ rather than at build-time (if possible of course). By calling
|
|||||||
struct, your program can figure out exactly what the currently running libcurl
|
struct, your program can figure out exactly what the currently running libcurl
|
||||||
supports.
|
supports.
|
||||||
|
|
||||||
.SH "Handle the Easy libcurl"
|
.SH "Two Interfaces"
|
||||||
libcurl first introduced the so called easy interface. All operations in the
|
libcurl first introduced the so called easy interface. All operations in the
|
||||||
easy interface are prefixed with 'curl_easy'.
|
easy interface are prefixed with 'curl_easy'. The easy interface lets you do
|
||||||
|
single transfers with a synchronous and blocking function call.
|
||||||
Recent libcurl versions also offer the multi interface. More about that
|
|
||||||
interface, what it is targeted for and how to use it is detailed in a separate
|
|
||||||
chapter further down. You still need to understand the easy interface first,
|
|
||||||
so please continue reading for better understanding.
|
|
||||||
|
|
||||||
|
libcurl also offers another interface that allows multiple simultaneous
|
||||||
|
transfers in a single thread, the so called multi interface. More about that
|
||||||
|
interface is detailed in a separate chapter further down. You still need to
|
||||||
|
understand the easy interface first, so please continue reading for better
|
||||||
|
understanding.
|
||||||
|
.SH "Handle the Easy libcurl"
|
||||||
To use the easy interface, you must first create yourself an easy handle. You
|
To use the easy interface, you must first create yourself an easy handle. You
|
||||||
need one handle for each easy session you want to perform. Basically, you
|
need one handle for each easy session you want to perform. Basically, you
|
||||||
should use one handle for every thread you plan to use for transferring. You
|
should use one handle for every thread you plan to use for transferring. You
|
||||||
@@ -162,13 +164,18 @@ transfer or series of transfers.
|
|||||||
You set properties and options for this handle using
|
You set properties and options for this handle using
|
||||||
\fIcurl_easy_setopt(3)\fP. They control how the subsequent transfer or
|
\fIcurl_easy_setopt(3)\fP. They control how the subsequent transfer or
|
||||||
transfers will be made. Options remain set in the handle until set again to
|
transfers will be made. Options remain set in the handle until set again to
|
||||||
something different. Alas, multiple requests using the same handle will use
|
something different. They are sticky. Multiple requests using the same handle
|
||||||
the same options.
|
will use the same options.
|
||||||
|
|
||||||
|
If you at any point would like to blank all previously set options for a
|
||||||
|
single easy handle, you can call \fIcurl_easy_reset(3)\fP and you can also
|
||||||
|
make a clone of an easy handle (with all its set options) using
|
||||||
|
\fIcurl_easy_duphandle(3)\fP.
|
||||||
|
|
||||||
Many of the options you set in libcurl are "strings", pointers to data
|
Many of the options you set in libcurl are "strings", pointers to data
|
||||||
terminated with a zero byte. When you set strings with
|
terminated with a zero byte. When you set strings with
|
||||||
\fIcurl_easy_setopt(3)\fP, libcurl makes its own copy so that they don't
|
\fIcurl_easy_setopt(3)\fP, libcurl makes its own copy so that they don't need
|
||||||
need to be kept around in your application after being set[4].
|
to be kept around in your application after being set[4].
|
||||||
|
|
||||||
One of the most basic properties to set in the handle is the URL. You set your
|
One of the most basic properties to set in the handle is the URL. You set your
|
||||||
preferred URL to transfer with \fICURLOPT_URL(3)\fP in a manner similar to:
|
preferred URL to transfer with \fICURLOPT_URL(3)\fP in a manner similar to:
|
||||||
@@ -1295,39 +1302,44 @@ To avoid this problem, you must of course use your common sense. Often, you
|
|||||||
can just edit out the sensitive data or just search/replace your true
|
can just edit out the sensitive data or just search/replace your true
|
||||||
information with faked data.
|
information with faked data.
|
||||||
|
|
||||||
.SH "Multiple Transfers Using the multi Interface"
|
.SH "The multi Interface"
|
||||||
|
|
||||||
The easy interface as described in detail in this document is a synchronous
|
The easy interface as described in detail in this document is a synchronous
|
||||||
interface that transfers one file at a time and doesn't return until it is
|
interface that transfers one file at a time and doesn't return until it is
|
||||||
done.
|
done.
|
||||||
|
|
||||||
The multi interface, on the other hand, allows your program to transfer
|
The multi interface, on the other hand, allows your program to transfer
|
||||||
multiple files in both directions at the same time, without forcing you
|
multiple files in both directions at the same time, without forcing you to use
|
||||||
to use multiple threads. The name might make it seem that the multi
|
multiple threads. The name might make it seem that the multi interface is for
|
||||||
interface is for multi-threaded programs, but the truth is almost the
|
multi-threaded programs, but the truth is almost the reverse. The multi
|
||||||
reverse. The multi interface can allow a single-threaded application
|
interface allows a single-threaded application to perform the same kinds of
|
||||||
to perform the same kinds of multiple, simultaneous transfers that
|
multiple, simultaneous transfers that multi-threaded programs can perform. It
|
||||||
multi-threaded programs can perform. It allows many of the benefits
|
allows many of the benefits of multi-threaded transfers without the complexity
|
||||||
of multi-threaded transfers without the complexity of managing and
|
of managing and synchronizing many threads.
|
||||||
synchronizing many threads.
|
|
||||||
|
To complicate matters somewhat more, there are even two versions of the multi
|
||||||
|
interface. The event based one, also called multi_socket and the "normal one"
|
||||||
|
designed for using with select(). See the libcurl-multi.3 man page for details
|
||||||
|
on the multi_socket event based API, this description here is for the select()
|
||||||
|
oriented one.
|
||||||
|
|
||||||
To use this interface, you are better off if you first understand the basics
|
To use this interface, you are better off if you first understand the basics
|
||||||
of how to use the easy interface. The multi interface is simply a way to make
|
of how to use the easy interface. The multi interface is simply a way to make
|
||||||
multiple transfers at the same time by adding up multiple easy handles into
|
multiple transfers at the same time by adding up multiple easy handles into
|
||||||
a "multi stack".
|
a "multi stack".
|
||||||
|
|
||||||
You create the easy handles you want and you set all the options just like you
|
You create the easy handles you want, one for each concurrent transfer, and
|
||||||
have been told above, and then you create a multi handle with
|
you set all the options just like you learned above, and then you create a
|
||||||
\fIcurl_multi_init(3)\fP and add all those easy handles to that multi handle
|
multi handle with \fIcurl_multi_init(3)\fP and add all those easy handles to
|
||||||
with \fIcurl_multi_add_handle(3)\fP.
|
that multi handle with \fIcurl_multi_add_handle(3)\fP.
|
||||||
|
|
||||||
When you've added the handles you have for the moment (you can still add new
|
When you've added the handles you have for the moment (you can still add new
|
||||||
ones at any time), you start the transfers by calling
|
ones at any time), you start the transfers by calling
|
||||||
\fIcurl_multi_perform(3)\fP.
|
\fIcurl_multi_perform(3)\fP.
|
||||||
|
|
||||||
\fIcurl_multi_perform(3)\fP is asynchronous. It will only execute as little as
|
\fIcurl_multi_perform(3)\fP is asynchronous. It will only perform what can be
|
||||||
possible and then return back control to your program. It is designed to never
|
done now and then return back control to your program. It is designed to never
|
||||||
block.
|
block. You need to keep calling the function until all transfers are
|
||||||
|
completed.
|
||||||
|
|
||||||
The best usage of this interface is when you do a select() on all possible
|
The best usage of this interface is when you do a select() on all possible
|
||||||
file descriptors or sockets to know when to call libcurl again. This also
|
file descriptors or sockets to know when to call libcurl again. This also
|
||||||
@@ -1340,11 +1352,12 @@ When you then call select(), it'll return when one of the file handles signal
|
|||||||
action and you then call \fIcurl_multi_perform(3)\fP to allow libcurl to do
|
action and you then call \fIcurl_multi_perform(3)\fP to allow libcurl to do
|
||||||
what it wants to do. Take note that libcurl does also feature some time-out
|
what it wants to do. Take note that libcurl does also feature some time-out
|
||||||
code so we advise you to never use very long timeouts on select() before you
|
code so we advise you to never use very long timeouts on select() before you
|
||||||
call \fIcurl_multi_perform(3)\fP, which thus should be called unconditionally
|
call \fIcurl_multi_perform(3)\fP again. \fIcurl_multi_timeout(3)\fP is
|
||||||
every now and then even if none of its file descriptors have signaled
|
provided to help you get a suitable timeout period.
|
||||||
ready. Another precaution you should use: always call
|
|
||||||
\fIcurl_multi_fdset(3)\fP immediately before the select() call since the
|
Another precaution you should use: always call \fIcurl_multi_fdset(3)\fP
|
||||||
current set of file descriptors may change when calling a curl function.
|
immediately before the select() call since the current set of file descriptors
|
||||||
|
may change in any curl function invoke.
|
||||||
|
|
||||||
If you want to stop the transfer of one of the easy handles in the stack, you
|
If you want to stop the transfer of one of the easy handles in the stack, you
|
||||||
can use \fIcurl_multi_remove_handle(3)\fP to remove individual easy
|
can use \fIcurl_multi_remove_handle(3)\fP to remove individual easy
|
||||||
|
Reference in New Issue
Block a user