首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用C++和libcurl向ONVIF摄像机发送SOAP请求?

如何使用C++和libcurl向ONVIF摄像机发送SOAP请求?
EN

Stack Overflow用户
提问于 2022-09-01 12:09:45
回答 1查看 32关注 0票数 0

下面是我如何尝试在C++。

代码语言:javascript
运行
复制
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>

struct MemoryStruct {
    char *memory;
    size_t size;
};

int main()
{
    std::string pstFld = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:tds=\"http://www.onvif.org/ver10/device/wsdl\"><SOAP-ENV:Body><tds:GetSystemDateAndTime/></SOAP-ENV:Body></SOAP-ENV:Envelope>";
    CURL *curl;
    CURLcode res;

    struct MemoryStruct chunk;
    chunk.memory = (char *) malloc(1);
    chunk.size = 0;

    curl_global_init(CURL_GLOBAL_ALL);
    curl = curl_easy_init();

    if (curl)
    {
        struct curl_slist *slist = NULL;
        slist = curl_slist_append(slist, "Host: my_ip_address");
        slist = curl_slist_append(slist, "Content-Type: text/xml; charset=utf-8");
        std::string contentLength = "Content-Length: " + std::to_string(pstFld.size());
        slist = curl_slist_append(slist, contentLength.c_str());
        curl_easy_setopt(curl, CURLOPT_URL, "http://my_ip_address/onvif/device_service");
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_easy_setopt(curl, CURLOPT_POST, true);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, pstFld);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &chunk);
        curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

        res = curl_easy_perform(curl);

        if (res != CURLE_OK)
        {
            fprintf(stderr, "Failed: %s\n", curl_easy_strerror(res));
        }
        else
        {
            printf("%lu bytes retrieved.\n", (unsigned long) chunk.size);
        }

        curl_easy_cleanup(curl);
        curl = NULL;
    }

    free(chunk.memory);
    curl_global_cleanup();

    return 0;
}

下面是来自curl_easy_strerror(res)的消息。

代码语言:javascript
运行
复制
* upload completely sent off: 6 out of 6 bytes
* Empty reply from server
Failed: Server returned nothing (no headers, no data)

我需要做什么才能从ONVIF获得响应数据?

请注意,我可以使用PHP成功地将SOAP请求发送到同一个ONVIF摄像机,并获得XML,但是使用C++,我可以发送请求,但没有得到响应。

EN

回答 1

Stack Overflow用户

发布于 2022-11-01 15:33:44

我终于找到了解决办法。

代码语言:javascript
运行
复制
#include <curl/curl.h>
#include <iostream>

static size_t handleResponse(void *contents, size_t length, size_t nmemb, void *userp)
{
     ((std::string*)userp)->append((char*)contents, length * nmemb);
     return length * nmemb;
}

int main()
{
    std::string readBuffer;
    CURL *curl;
    CURLcode res;
    std::string postField = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Body xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><GetSystemDateAndTime xmlns=\"http://www.onvif.org/ver10/device/wsdl\" /></s:Body></s:Envelope>";
    curl = curl_easy_init();

    if (curl)
    {
        struct curl_slist *slist = NULL;
        slist = curl_slist_append(slist, "Accept: */*");
        slist = curl_slist_append(slist, "Content-Type: text/xml");
        std::string content_length = "Content-Length: " + std::to_string(postField.size());

        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
        curl_easy_setopt(curl, CURLOPT_HEADER, 0);
        curl_easy_setopt(curl, CURLOPT_URL, "http://my_ip_address/onvif/device_service");
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postField.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handleResponse);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
        res = curl_easy_perform(curl);

        if (res != CURLE_OK)
        {
            std::cout << "Failed." << std::endl;
        }

        curl_easy_cleanup(curl);
        curl_slist_free_all(slist);
    }

    return 0;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73569124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档