下面是我如何尝试在C++。
#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)
的消息。
* 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++,我可以发送请求,但没有得到响应。
发布于 2022-11-01 15:33:44
我终于找到了解决办法。
#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;
}
https://stackoverflow.com/questions/73569124
复制相似问题