ONVIF 設備發現(網絡攝像頭)——實例筆記

相關配置

ONVIF官網:http://www.onvif.org/
gSOAP安裝配置:gSOAP安裝配置+使用案例參考+參考鏈接
操作系統:CentOS7

資料參考:

許振坪的ONVIF專欄:傳送門
onvif開發之設備發現功能的實現
Linux下onvif服務端之發現設備
還有一個博文找不到網址了,如果網友發現可以私信補充。

代碼實戰

客戶端

1、WS-Discovery的Ad hoc模式,使用多播(不使用gSOAP實現設備發現)

參考文章:ONVIF協議網絡攝像機(IPC)客戶端程序開發(7):設備搜索
源碼如下 search_c.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef WIN32
#include <winsock.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif

/* 從技術層面來說,通過單播、多播、廣播三種方式都能探測到IPC,但多播最具實用性*/
#define COMM_TYPE_UNICAST         1                                             // 單播
#define COMM_TYPE_MULTICAST       2                                             // 多播
#define COMM_TYPE_BROADCAST       3                                             // 廣播
#define COMM_TYPE                 COMM_TYPE_MULTICAST

/* 發送探測消息(Probe)的目標地址、端口號 */
#if COMM_TYPE == COMM_TYPE_UNICAST
    #define CAST_ADDR "100.100.100.15"                                          // 單播地址,預先知道的IPC地址
#elif COMM_TYPE == COMM_TYPE_MULTICAST
    #define CAST_ADDR "239.255.255.250"                                         // 多播地址,固定的239.255.255.250
#elif COMM_TYPE == COMM_TYPE_BROADCAST
    #define CAST_ADDR "100.100.100.255"                                         // 廣播地址
#endif

#define CAST_PORT 3702                                                          // 端口號

/* 以下幾個宏是爲了socket編程能夠跨平臺,這幾個宏是從gsoap中拷貝來的 */
#ifndef SOAP_SOCKET
# ifdef WIN32
#  define SOAP_SOCKET SOCKET
#  define soap_closesocket(n) closesocket(n)
# else
#  define SOAP_SOCKET int
#  define soap_closesocket(n) close(n)
# endif
#endif

#if defined(_AIX) || defined(AIX)
# if defined(_AIX43)
#  define SOAP_SOCKLEN_T socklen_t
# else
#  define SOAP_SOCKLEN_T int
# endif
#elif defined(SOCKLEN_T)
# define SOAP_SOCKLEN_T SOCKLEN_T
#elif defined(__socklen_t_defined) || defined(_SOCKLEN_T) || defined(CYGWIN) || defined(FREEBSD) || defined(__FreeBSD__) || defined(OPENBSD) || defined(__QNX__) || defined(QNX) || defined(OS390) || defined(__ANDROID__) || defined(_XOPEN_SOURCE)
# define SOAP_SOCKLEN_T socklen_t
#elif defined(IRIX) || defined(WIN32) || defined(__APPLE__) || defined(SUN_OS) || defined(OPENSERVER) || defined(TRU64) || defined(VXWORKS) || defined(HP_UX)
# define SOAP_SOCKLEN_T int
#elif !defined(SOAP_SOCKLEN_T)
# define SOAP_SOCKLEN_T size_t
#endif

#ifdef WIN32
#define SLEEP(n)    Sleep(1000 * (n))
#else
#define SLEEP(n)    sleep((n))
#endif

/* 探測消息(Probe),這些內容是ONVIF Device Test Tool 15.06工具搜索IPC時的Probe消息,通過Wireshark抓包工具抓包到的 */
const char *probe = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Envelope xmlns:dn=\"http://www.onvif.org/ver10/network/wsdl\" xmlns=\"http://www.w3.org/2003/05/soap-envelope\"><Header><wsa:MessageID xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">uuid:fc0bad56-5f5a-47f3-8ae2-c94a4e907d70</wsa:MessageID><wsa:To xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To><wsa:Action xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</wsa:Action></Header><Body><Probe xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><Types>dn:NetworkVideoTransmitter</Types><Scopes /></Probe></Body></Envelope>";

int main(int argc, char **argv)
{
    int ret;
    int optval;
    SOAP_SOCKET s;
    SOAP_SOCKLEN_T len;
    char recv_buff[4096] = {0};
    struct sockaddr_in multi_addr;
    struct sockaddr_in client_addr;

#ifdef WIN32
    WSADATA wsaData;
    if( WSAStartup(MAKEWORD(2,2), &wsaData) != 0 ) {                             // 初始化Windows Sockets DLL
        printf("Could not open Windows connection.\n");
        return 0;
    }
    if ( LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 ) {
        printf("the version of WinSock DLL is not 2.2.\n");
        return 0;
    }
#endif

    s = socket(AF_INET, SOCK_DGRAM, 0);                                         // 建立數據報套接字
    if (s < 0) {
        perror("socket error");
        return -1;
    }

#if COMM_TYPE == COMM_TYPE_BROADCAST
    optval = 1;
    ret = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (const char*)&optval, sizeof(int));
#endif

    multi_addr.sin_family = AF_INET;                                            // 搜索IPC:使用UDP向指定地址發送探測消息(Probe)
    multi_addr.sin_port = htons(CAST_PORT);
    multi_addr.sin_addr.s_addr = inet_addr(CAST_ADDR);
    ret = sendto(s, probe, strlen(probe), 0, (struct sockaddr*)&multi_addr, sizeof(multi_addr));
    if (ret < 0) {
        soap_closesocket(s);
        perror("sendto error");
        return -1;
    }
    printf("Send Probe message to [%s:%d]\n\n", CAST_ADDR, CAST_PORT);
    SLEEP(1);

    for (;;) {                                                                  // 接收IPC的應答消息(ProbeMatch)
        len = sizeof(client_addr);
        memset(recv_buff, 0, sizeof(recv_buff));
        memset(&client_addr, 0, sizeof(struct sockaddr));
        ret = recvfrom(s, recv_buff, sizeof(recv_buff) - 1, 0, (struct sockaddr*)&client_addr, &len);
        printf("===Recv ProbeMatch from [%s:%d]===\n%s\n\n",  inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), recv_buff);
        SLEEP(1);
    }
    soap_closesocket(s);

    return 0;
}

Linux編譯: gcc search_c.c , Windows下編譯: gcc search_c.c -lws2_32
Windows下效果和Linux下效果一樣。
在這裏插入圖片描述
我Linux是用的虛擬機,所以需要關閉防火牆,不然搜不到 systemctl stop iptables.serviceservice iptables stop

我們也使用 ONVIF Device Test Tool在這裏插入圖片描述,測一下
在這裏插入圖片描述

2、使用gSOAP生成ONVIF框架,編寫客戶端

如何生成ONVIF框架參考:ONVIF協議網絡攝像機(IPC)客戶端程序開發(6):使用gSOAP生成ONVIF框架代碼,原文沒有生成soapServer.c,我在評論裏面寫了如何修改,可以參考。
部分文件下載於:GitHub
參考文章:onvif開發之設備發現功能的實現
我做的相關改動都寫在評論區了,server編譯通不過,但client是可行的。
在這裏插入圖片描述
client.c源碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <uuid/uuid.h>
#include "soapH.h"
#include "soapStub.h"
#include "wsdd.nsmap"
#include "wsaapi.h"

#define MULTICAST_ADDRESS "soap.udp://239.255.255.250:3702"  

int main()  
{  
	printf("[%s][%d][%s][%s] start \n", __FILE__, __LINE__, __TIME__, __func__);
 
	int result = 0;  
	wsdd__ProbeType req;
	struct __wsdd__ProbeMatches resp;
	wsdd__ScopesType sScope;
	struct SOAP_ENV__Header header;  
	
	struct soap *soap;  
	soap = soap_new();  
	if(NULL == soap )  
	{  
		printf("sopa new error\r\n");  
		return -1;  
	}  
 
	soap->recv_timeout = 10;  
	soap_set_namespaces(soap, namespaces);  
	soap_default_SOAP_ENV__Header(soap, &header);  
 
	uuid_t uuid;
	char guid_string[100];
	uuid_generate(uuid);
	uuid_unparse(uuid, guid_string);
 
	header.wsa__MessageID = guid_string; 
	header.wsa__To = "urn:schemas-xmlsoap-org:ws:2005:04:discovery";  
	header.wsa__Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe";  
	soap->header = &header;  
	
	soap_default_wsdd__ScopesType(soap, &sScope);  
	sScope.__item = "";  
	soap_default_wsdd__ProbeType(soap, &req);  
	req.Scopes = &sScope;  
	req.Types = "dn:NetworkVideoTransmitter";
 //"dn:NetworkVideoTransmitter";  
 
	int i = 0;  	
       result = soap_send___wsdd__Probe(soap, MULTICAST_ADDRESS, NULL, &req);  
       while(result == SOAP_OK)  
       {  
		result = soap_recv___wsdd__ProbeMatches(soap, &resp);  
		if(result == SOAP_OK)  
		{  
			if(soap->error)  
			{  
				printf("soap error 1: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap));  
				result = soap->error;  
			}  
			else  
			{  
				printf("guog *********************************************\r\n");  
				if(soap->header->wsa__MessageID)  
				{  
					printf("MessageID   : %s\r\n", soap->header->wsa__MessageID);  
				}  
				if(soap->header->wsa__RelatesTo && soap->header->wsa__RelatesTo->__item)  
				{  
					printf("RelatesTo   : %s\r\n", soap->header->wsa__RelatesTo->__item);  
				}  
				if(soap->header->wsa__To)  
				{  
					printf("To          : %s\r\n", soap->header->wsa__To);  
				}  
				if(soap->header->wsa__Action)  
				{  
					printf("Action      : %s\r\n", soap->header->wsa__Action);  
				}  
 
				for(i = 0; i < resp.wsdd__ProbeMatches->__sizeProbeMatch; i++)  
				{  
					printf("__sizeProbeMatch        : %d\r\n", resp.wsdd__ProbeMatches->__sizeProbeMatch);  
					printf("wsa__EndpointReference       : %p\r\n", resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference);  
					printf("Target EP Address       : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference.Address);  
					printf("Target Type             : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->Types);  
					printf("Target Service Address  : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->XAddrs);  
					printf("Target Metadata Version : %d\r\n", resp.wsdd__ProbeMatches->ProbeMatch->MetadataVersion);  
					if(resp.wsdd__ProbeMatches->ProbeMatch->Scopes)  
					{  
						printf("Target Scopes Address   : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->Scopes->__item);  
					}  
				}
			}  
		}  
		else if (soap->error)  
		{  
			printf("[%d] soap error 2: %d, %s, %s\n", __LINE__, soap->error, *soap_faultcode(soap), *soap_faultstring(soap));  
			result = soap->error;  
		}  
       }  
 
	soap_destroy(soap); 
	soap_end(soap); 
	soap_free(soap);
 
	printf("[%d] guog discover over !\n", __LINE__);
	
	return result;  
}  

Linux下編譯: gcc -o client client.c stdsoap2.c soapC.c soapClient.c wsaapi.c duration.c -luuid
沒有libuuid庫,可自行安裝,命令僅供參考 sudo apt-get install uuid-dev
效果如圖:
在這裏插入圖片描述

服務端

1、不使用gSOAP,虛擬機僞裝成ipc

文章參考:Linux下onvif服務端之發現設備
代碼如下 ipc_server_c.c:

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <netdb.h>
//#include <errno.h>
//#include <uuid/uuid.h>
 
#define BUFLEN 4095
 
int main (int argc, char **argv) 
{
    char uu_buf[1024]={0};
    char *cust_uuid = 0;
	
    struct sockaddr_in groupcast_addr,the_member;
    int sockfd; 
    unsigned char loop;
    char recmsg[BUFLEN + 1]; 
    unsigned int socklen, n; 
    struct ip_mreq mreq; 
#if 0
    char *msg="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:SOAP-ENC=\"http://www.w3.org/2003/05/soap-encoding\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" xmlns:wsdd=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:chan=\"http://schemas.microsoft.com/ws/2005/02/duplex\" xmlns:wsa5=\"http://www.w3.org/2005/08/addressing\" xmlns:xmime=\"http://tempuri.org/xmime.xsd\" xmlns:xop=\"http://www.w3.org/2004/08/xop/include\" xmlns:tt=\"http://www.onvif.org/ver10/schema\" xmlns:wsrfbf=\"http://docs.oasis-open.org/wsrf/bf-2\" xmlns:wstop=\"http://docs.oasis-open.org/wsn/t-1\" xmlns:wsrfr=\"http://docs.oasis-open.org/wsrf/r-2\" xmlns:tdn=\"http://www.onvif.org/ver10/network/wsdl\" xmlns:tds=\"http://www.onvif.org/ver10/device/wsdl\" xmlns:tev=\"http://www.onvif.org/ver10/events/wsdl\" xmlns:wsnt=\"http://docs.oasis-open.org/wsn/b-2\" xmlns:tptz=\"http://www.onvif.org/ver20/ptz/wsdl\" xmlns:trt=\"http://www.onvif.org/ver10/media/wsdl\">\n\
<SOAP-ENV:Header>\n\
<wsa:MessageID>uuid:2419d68a-2dd2-21b2-a205-4A69A95DB56D</wsa:MessageID>\n\
<wsa:RelatesTo>uuid:251984b5-d773-4d2e-a21d-d248cdd2eebf</wsa:RelatesTo>\n\
<wsa:To SOAP-ENV:mustUnderstand=\"true\">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>\n\
<wsa:Action SOAP-ENV:mustUnderstand=\"true\">http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches</wsa:Action>\n\
</SOAP-ENV:Header>\n\
<SOAP-ENV:Body>\n\
<wsdd:ProbeMatches>\n\
<wsdd:ProbeMatch>\n\
<wsa:EndpointReference>\n\
<wsa:Address>urn:uuid:2419d68a-2dd2-21b2-a205-4A69A95DB56D</wsa:Address>\n\
<wsa:ReferenceProperties />\n\
<wsa:ReferenceParameters />\n\
<wsa:PortType>ttl</wsa:PortType>\n\
</wsa:EndpointReference>\n\
<wsdd:Types>tds:Device</wsdd:Types>\n\
<wsdd:Scopes>onvif://www.onvif.org/type/NetworkVideoTransmitter\r\nonvif://www.onvif.org/name/IPC_2802222\r\nonvif://www.onvif.org/location/Country/China</wsdd:Scopes>\n\
<wsdd:XAddrs>http://192.168.42.103:5000/onvif/device_service</wsdd:XAddrs>\n\
<wsdd:MetadataVersion>1</wsdd:MetadataVersion>\n\</wsdd:ProbeMatch>\n\
</wsdd:ProbeMatches>\n\
</SOAP-ENV:Body>\n\
</SOAP-ENV:Envelope>\n\n";
#endif
 
    char *aa= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:SOAP-ENC=\"http://www.w3.org/2003/05/soap-encoding\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" xmlns:wsdd=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:chan=\"http://schemas.microsoft.com/ws/2005/02/duplex\" xmlns:wsa5=\"http://www.w3.org/2005/08/addressing\" xmlns:xmime=\"http://tempuri.org/xmime.xsd\" xmlns:xop=\"http://www.w3.org/2004/08/xop/include\" xmlns:tt=\"http://www.onvif.org/ver10/schema\" xmlns:wsrfbf=\"http://docs.oasis-open.org/wsrf/bf-2\" xmlns:wstop=\"http://docs.oasis-open.org/wsn/t-1\" xmlns:wsrfr=\"http://docs.oasis-open.org/wsrf/r-2\" xmlns:tdn=\"http://www.onvif.org/ver10/network/wsdl\" xmlns:tds=\"http://www.onvif.org/ver10/device/wsdl\" xmlns:tev=\"http://www.onvif.org/ver10/events/wsdl\" xmlns:wsnt=\"http://docs.oasis-open.org/wsn/b-2\" xmlns:tptz=\"http://www.onvif.org/ver20/ptz/wsdl\" xmlns:trt=\"http://www.onvif.org/ver10/media/wsdl\">\n\
<SOAP-ENV:Header>\n\
<wsa:MessageID>uuid:2419d68a-2dd2-21b2-a205-4A69A95DB56D</wsa:MessageID>\n\
<wsa:RelatesTo>uuid:";
 
    char *bb = "</wsa:RelatesTo>\n\
<wsa:To SOAP-ENV:mustUnderstand=\"true\">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>\n\
<wsa:Action SOAP-ENV:mustUnderstand=\"true\">http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches</wsa:Action>\n\
</SOAP-ENV:Header>\n\
<SOAP-ENV:Body>\n\
<wsdd:ProbeMatches>\n\
<wsdd:ProbeMatch>\n\
<wsa:EndpointReference>\n\
<wsa:Address>urn:uuid:2419d68a-2dd2-21b2-a205-4A69A95DB56D</wsa:Address>\n\
<wsa:ReferenceProperties />\n\
<wsa:ReferenceParameters />\n\
<wsa:PortType>ttl</wsa:PortType>\n\
</wsa:EndpointReference>\n\
<wsdd:Types>tds:Device</wsdd:Types>\n\
<wsdd:Scopes>onvif://www.onvif.org/type/NetworkVideoTransmitter\r\nonvif://www.onvif.org/name/IPC_2802222\r\nonvif://www.onvif.org/location/Country/China</wsdd:Scopes>\n\
<wsdd:XAddrs>http://192.168.42.100:5000/onvif/device_service</wsdd:XAddrs>\n\
<wsdd:MetadataVersion>1</wsdd:MetadataVersion>\n\</wsdd:ProbeMatch>\n\
</wsdd:ProbeMatches>\n\
</SOAP-ENV:Body>\n\
</SOAP-ENV:Envelope>\n\n";
 
    /* 創建 socket 用於UDP通訊 */ 
    sockfd = socket (AF_INET, SOCK_DGRAM, 0); 
    if (sockfd < 0)
    {          
        printf ("socket creating err in udptalk\n");          
        exit (1);        
    } 
    /* 設置要加入組播的地址 */ 
    bzero(&mreq, sizeof (struct ip_mreq));
    
    inet_pton(AF_INET,"239.255.255.250",&the_member.sin_addr);
    /* 設置組地址 */ 
    bcopy (&the_member.sin_addr.s_addr, &mreq.imr_multiaddr.s_addr, sizeof (struct in_addr)); 
    /* 設置發送組播消息的源主機的地址信息 */ 
    mreq.imr_interface.s_addr = htonl (INADDR_ANY);  
    /* 把本機加入組播地址,即本機網卡作爲組播成員,只有加入組才能收到組播消息 */ 
    //if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP | IP_MULTICAST_LOOP, &mreq,sizeof (struct ip_mreq)) == -1)
    if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP , &mreq,sizeof (struct ip_mreq)) == -1)
    {
        perror ("setsockopt");
        exit (-1);   
    }
	loop = 0;
    if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop,sizeof (loop)) == -1)
    {
        printf("IP_MULTICAST_LOOP set fail!\n");
    }
	
    socklen = sizeof (struct sockaddr_in); 
    memset (&groupcast_addr, 0, socklen); 
    groupcast_addr.sin_family = AF_INET;
    groupcast_addr.sin_port = htons (3702);
    inet_pton(AF_INET, "239.255.255.250", &groupcast_addr.sin_addr); 
    /* 綁定自己的端口和IP信息到socket上 */ 
    if (bind(sockfd, (struct sockaddr *) &groupcast_addr,sizeof (struct sockaddr_in)) == -1)
    {      
        printf ("Bind error\n");      
        exit (0);    
    }
  
    while (1)
    {     
        bzero (recmsg, BUFLEN + 1); 
        n = recvfrom (sockfd, recmsg, BUFLEN, 0, (struct sockaddr *) &the_member, &socklen);
        if (n < 0)
        {      
            printf ("recvfrom err in udptalk!\n");      
            exit (4);    
        }
        else{      
            recmsg[n] = 0;      
            printf ("recv:[%s]\n\n", recmsg);    
            printf("ip:%s\n",inet_ntoa(the_member.sin_addr));
            printf("port:%d\n", ntohs(the_member.sin_port));
        }
		
        cust_uuid = strstr(recmsg, "uuid:"); //獲取recmsg字符串中 子字符串"uuid:"的位置
        if (cust_uuid == 0)
        {
            printf("uuid: err!\n");
            return 0;
        }
        cust_uuid += 5;   //獲取接收的uuid的值
        strncpy(uu_buf, cust_uuid, 36);
        printf("%s\n",uu_buf);
		
        memset(recmsg,0,sizeof(recmsg));
        strcpy(recmsg, aa);
        strcat(recmsg, uu_buf);
        strcat(recmsg, bb);
        if (sendto(sockfd, recmsg, strlen (recmsg), 0, (struct sockaddr *) &the_member, sizeof (the_member)) < 0)
        {      
            printf ("sendto error!\n");
            exit (3);
        }
        printf ("send ok\n");
        break;
    }
}

Linux下編譯:gcc ipc_server_c.c -o ipc_server
在這裏插入圖片描述
直接運行
在這裏插入圖片描述
現在我們用 ONVIF Device Test Tool,測試一下
在這裏插入圖片描述
ONVIF Device Test Tool 搜索後,服務端就打印了這些信息
在這裏插入圖片描述
ifconfig查看下虛擬機ip地址
在這裏插入圖片描述
同樣可以被我們之前寫的 客戶端 搜索到
在這裏插入圖片描述

2、使用gSOAP生成ONVIF框架,編寫服務端

文件下載於:GitHub
參考文章:onvif服務器篇之onvif 服務器框架的搭建
碰到的問題同樣寫在評論區,可自行查看。
在這裏插入圖片描述
修改Makefile,GSOAP_ROOT改成自己的soap路徑
在這裏插入圖片描述
終端 make 編譯。生成 deviceserver
我們直接運行 ./deviceserver
在這裏插入圖片描述
我們同樣用 ONVIF Device Test Tool,搜索一下
在這裏插入圖片描述
服務端也有所反應
在這裏插入圖片描述


那麼本次的服務端和客戶端都測試完畢了。網上資料不多,真的進行的十分困難。

相關鏈接

ONVIF官網:http://www.onvif.org/
gSOAP安裝配置:gSOAP安裝配置+使用案例參考+參考鏈接
許振坪的ONVIF專欄
onvif開發之設備發現功能的實現
Linux下onvif服務端之發現設備
ONVIF協議網絡攝像機(IPC)客戶端程序開發(7):設備搜索
ONVIF協議網絡攝像機(IPC)客戶端程序開發(6):使用gSOAP生成ONVIF框架代碼
onvif開發之設備發現功能的實現
Linux下onvif服務端之發現設備
GitHub服務端下載
onvif服務器篇之onvif 服務器框架的搭建
ONVIF Device Test Tool

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章