這個文檔是小編在curl官網上使用谷歌翻譯翻譯的,詳細資訊看官網
curl
描述
這是關于如何在 C 程式中使用 libcurl 多接口的概述。這裡提到的每個函數都有特定的手冊頁。還有libcurl-tutorial手冊頁用于使用 libcurl 進行程式設計的完整教程,以及libcurl-easy手冊頁用于概述 libcurl 簡易界面。
multi 接口中的所有函數都以 curl_multi 為字首。
特點
多界面提供了簡單界面所沒有的多種功能。它們主要是:
1.啟用“拉”接口。使用 libcurl 的應用程式決定何時何地要求 libcurl 擷取/發送資料。
2.在同一線程中啟用多個句柄同時傳輸,而不會使應用程式變得複雜。
3. 應用程式能夠同時等待對其自己的檔案描述符和 curl 的檔案描述符的操作。
4. 啟用基于事件的處理并将傳輸擴充到數千個并行連接配接。
一個multi句柄多個easy句柄
multi 接口的使用流程:
1、要使用multi 接口,首先是要使用curl_multi_init建立一個“multi句柄” 。然後,此句柄用作所有其他 curl_multi_* 函數的輸入。
2、使用多句柄和多接口,可以并行進行多個傳輸流程。每個單次傳輸都是圍繞一個簡單的搖桿建立的。是以我們需要建立所需的所有簡單句柄,并使用curl_easy_setopt為每個簡單句柄設定适當的選項。
3、多接口有兩種風格,一種是面向 select() 的,一種是基于事件的,我們稱之為 multi_socket。下面将是對這兩種方式的講解,以了解它們的工作原理和差別。
**select() 的方式:主要講述一些函數的使用 **
當一個多句柄設定并準備好傳輸時,并不是像使用簡單接口進行傳輸時那樣使用curl_easy_perform
而是需要将所有的簡單 句柄使用函數curl_multi_add_handle添加到多句柄。我們随時将簡單的句柄添加到多句柄,即使其他傳輸已經在運作。
而當 我們使用完簡單句柄之後可以使用curl_multi_remove_handle從多句柄的堆棧中删除簡單句柄。從多句柄中移除後,仍然可以再次使用其他簡單的界面功能。
需要注意的是将簡單句柄添加到多句柄不會啟動傳輸。多句柄的傳輸是由curl_multi_perform來推動傳輸。多此界面的主要思想之一是讓應用程式驅動傳輸。如果有任何可傳輸的内容,它将在目前多句柄堆棧中所有正在傳輸的任務(無論在傳輸啥東西)中傳輸資料進行傳輸。這可能是全部,也可能沒有。當現在沒有更多事情要做時,它會傳回到調用應用程式。
我們要是想擷取libcurl是何時被程式所調用、資料傳輸資訊和其他工作資訊的話 ,我們可以使用curl_multi_poll,這個函數會在應用程式下次調用libcurl的時候,它從 libcurl 中提取 fd_set 以便在 select() 或 poll() 調用中使用,進而了解何時需要注意多堆棧中的傳輸。之前使用的API 是curl_multi_fdset。這兩個 API 都允許您的程式同時等待您自己的私有檔案描述符的輸入。curl_multi_timeout還可以幫助您為 select() 調用提供合适的逾時時間。
curl_multi_perform将正在 運作傳輸的任務數量純純在其輸入的參數之中,我們可通過讀取此參數,進而确定多句柄中的所有傳輸何時完成。“完成”并不意味着成功。一項或多項傳輸可能已失敗。
要擷取有關已完成傳輸的資訊,以确定是否成功,應調用curl_multi_info_read 。它可以傳回有關目前或先前傳輸的消息。重複調用該函數會獲得更多消息,直到消息隊列為空。您在那裡收到的資訊包括一個易于處理的指針,您可以使用它來識别哪些易于處理的資訊涉及。
單次傳輸完成後,簡單句柄仍會添加到多堆棧中。您需要首先使用 curl_multi_remove_handle 删除簡單句柄,然後使用curl_easy_cleanup将其關閉,或者可能為其設定新選項并使用curl_multi_add_handle再次添加以開始另一次傳輸。
當多堆棧中的所有傳輸完成後,使用curl_multi_cleanup關閉多句柄。請注意,您必須為每個簡單的句柄調用單獨的curl_easy_cleanup調用以正确清理它們。
如果您想重新使用添加到多搖桿的簡單搖桿進行傳輸,您必須首先将其從多堆棧中移除,然後再次重新添加(可能在您選擇更改某些選項之後)。
多套接字的使用:
curl_multi_socket_action函數為應用程式提供了一種方法,他不僅可以避免被迫使用 select(),而且還提供了更高性能的 API,這将對使用大量同時連接配接的應用程式産生重大影響。
使用curl_multi_socket_action代替curl_multi_perform。
使用此 API 時,您可以像使用普通的多接口一樣将簡單的句柄添加到多句柄。然後,您還使用CURLMOPT_SOCKETFUNCTION和CURLMOPT_TIMERFUNCTION選項将兩個回調設定為curl_multi_setopt。它們是 libcurl 将調用的兩個回調函數,其中包含有關等待哪些套接字、進行哪些活動以及目前逾時時間的資訊 - 如果過期,則應通知 libcurl。
multi_socket API 旨在通知您的應用程式 libcurl 目前正在使用哪些套接字,以及您的應用程式預期在這些套接字上等待哪些活動(讀取和/或寫入)。
您的應用程式必須確定接收到在CURLMOPT_SOCKETFUNCTION回調中通知的所有套接字,并確定它對它們上的給定活動做出反應。當套接字具有給定的活動時,您調用curl_multi_socket_action指定存在的套接字和操作。
調用 CURLMOPT_TIMERFUNCTION回調來設定逾時。當該逾時到期時,您的應用程式應該調用curl_multi_socket_action函數,說明這是由于逾時。
此 API 通常與應用程式“訂閱”套接字更改的事件驅動的底層功能(如 libevent、libev、kqueue、epoll 或類似功能)一起使用。這允許應用程式和 libcurl 更好地向上擴充并超過數千個同時傳輸而不會損失性能。
添加初始句柄集後,調用curl_multi_socket_action并在 sockfd 參數中設定 CURL_SOCKET_TIMEOUT ,您将獲得設定您的回調調用,然後當您在被詢問的套接字上獲得活動時繼續調用curl_multi_socket_action等待,或者逾時計時器到期。
您可以輪詢curl_multi_info_read以檢視是否有任何傳輸已完成,因為它會顯示一條消息。
阻塞
代碼中的一些區域仍在使用阻塞代碼,即使從多界面使用也是如此。雖然我們當然希望并打算在未來修複這些問題,但您應該了解以下目前限制:
- 名稱解析,除非使用 c-ares 或線程解析器後端 - 檔案:// 傳輸 - TELNET 傳輸