【问题标题】:Libcurl and HTTP PipeliningLibcurl 和 HTTP 流水线
【发布时间】:2015-08-25 22:39:16
【问题描述】:

Libcurl 提供 CURLOPT_HEADERFUNCTION 和 CURLOPT_WRITEFUNCTION 回调。在您使用流水线和多堆栈之前,这很好。您如何将标题与正文相关联?假设大量的请求和一堆简单的句柄导致 libcurl 建立到服务器的多个连接。让我们假设第一个响应标头到达,并且接收主体有延迟。同时,第二个标题与正文一起出现。 libcurl 是否确保在第一个响应完成之前不会将第二个标头传递给应用程序? 这很重要,因为标题需要与正文相关联。即使我不使用 HEADERFUNCTION,我也处于同样的困境中。即使我只使用 WRITEFUNCTION,它也可能以混合方式接收乱序的回复。所以问题是:libcurl 是否确保响应作为一个整体交付?如果是单个连接,我们可以确定响应顺序会遵循请求顺序。但是当我使用管道和多堆栈时,我看到 libcurl 建立了多个连接。假设有 5 个连接到同一个服务器,因为我们在这里讨论的是流水线。 Conn1 的响应头到达,在我们从 Conn1 获取正文之前,我们从 Conn2 获取 ResponseHeader。 LibCurl 是否确保在 BodyFromConn1 之前不会将 Conn2ResponseHeader 传递给应用程序?否则下面的代码会中断。

class CEasyHandle
{
CURL*   m_pCurl;
bool    m_bInUse;
};

class CMultiStack
{
public:
CURLM* m_pCurlMulti;
deque<CEasyHandle*>& m_listEasyHandles;
static CEasyHandle* gpCurrentlyReceivingEasyHandle;

CEasyHandle* GetAvailableEasyHandle()
{
    // Iterate through m_listEasyHandles and find one that is currently not added to multistack (m_bInUse)
    // if none free, return NULL
}

bool MakeRequest(const char* pUrl)
{
    CEasyHandle* pEasyHandle = GetAvailableEasyHandle();
    if(!pEasyHandle) pEasyHandle = CreateNewEasyHandleAndAddToList();
    curl_easy_setopt(pEasyHandle->m_pCurl, CURLOPT_HEADERFUNCTION, header_callback);
    curl_easy_setopt(pEasyHandle->m_pCurl, CURLOPT_HEADERDATA, pEasyHandle); // header gets the EasyHandle
    curl_easy_setopt(pEasyHandle->m_pCurl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(pEasyHandle->m_pCurl, CURLOPT_WRITEDATA, this); // body gets MultiStack
    // set options, add to multistack, pEasyHandle->m_bInUse = true;
}

static size_t header_callback(char *buffer, size_t size, size_t nmemb, void *userdata)
{
    gpCurrentlyReceivingEasyHandle = (CEasyHandle*)userdata;
    // if no data expected, of course set gpCurrentlyReceivingEasyHandle->m_bInUse = false;
}

static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
    CMultiStack* pThisObj = (CMultiStack*)userdata;
    pThisObj->PerformSomeWork();
    // once complete, gpCurrentlyReceivingEasyHandle->m_bInUse = false;
}

};

【问题讨论】:

    标签: http libcurl


    【解决方案1】:

    为什么不使用CEasyHandle 作为WRITEFUNCTION 的用户数据?并在创建它们时在每个CEasyHandle 中存储指向CMultiStack 的反向指针?然后你总能在write_callback找到你需要的任何件,而且不用担心顺序。

    【讨论】:

      猜你喜欢
      • 2012-07-31
      • 2012-01-08
      • 2011-01-25
      • 2011-03-18
      • 2011-07-04
      • 1970-01-01
      • 2018-11-25
      • 1970-01-01
      • 2011-04-02
      相关资源
      最近更新 更多