前文
ONVIF专题--Onvif标准解读(2)--Core Spec::Device Discovery(1)
ONVIF专题--Onvif标准解读(2)--Core Spec::Device Discovery(2)
1 gsoap产生代码文件分析
经过 Onvif标准解读(2)--Core Spec::Device Discovery(2) 步骤产生了代码文件如下:
stdsoap2.h stdsoap2.cpp soapH.h soapClient.cpp soapClientLib.cpp soapServer.cpp soapServerLib.cpp soapStub.h wsdd.nsmap |
其中,stdsoap2.h,stdsoap2.cpp是gsoap提供的传输层接口和操作系统通用接口的封装,不是gsoap产生的,用户直接从.../gsoap路径下拷贝到工程即可。
而soapC.cpp,soapH.h中定义了与wsdl文件中定义协议相关的接口,协议解析、协议请求报文处理、回复报文处理、数据序列化操作等,属于协议栈的会话层、表示层接口。
soapStub.h、soapClient.cpp、soapServer.cpp 属于应用层接口,与wsdl定义的某条协议相对应。soapStub.h中申明了客户端和服务端的接口,但没有实现。客户端的接口,如soap_send___wsdd__Probe() 客户端发送询问请求是现在soapClient.cpp中;服务端接口如soap_serve___wsdd__Probe() 服务端收到询问请求的回调函数是现在soapServer.cpp中。
另外soapStub.h中还声明了服务端用户回调函数的原型,这一部分接口需要开发者手动实现:
__wsdd__Hello __wsdd__Bye __wsdd__Probe ... |
2 示例
服务端示例:
// 实现协议用户回调SOAP_FMAC5 int SOAP_FMAC6 SOAP_ENV__Fault(struct soap*, char *faultcode, char *faultstring, char *faultactor, struct SOAP_ENV__Detail *detail, struct SOAP_ENV__Code *SOAP_ENV__Code, struct SOAP_ENV__Reason *SOAP_ENV__Reason, char *SOAP_ENV__Node, char *SOAP_ENV__Role, struct SOAP_ENV__Detail *SOAP_ENV__Detail) { return 0; }
SOAP_FMAC5 int SOAP_FMAC6 __wsdd__Hello(struct soap*, struct wsdd__HelloType *wsdd__Hello) { return 0; }
SOAP_FMAC5 int SOAP_FMAC6 __wsdd__Bye(struct soap*, struct wsdd__ByeType *wsdd__Bye) { return 0; }
SOAP_FMAC5 int SOAP_FMAC6 __wsdd__Probe(struct soap*, struct wsdd__ProbeType *wsdd__Probe){return 0;}
SOAP_FMAC5 int SOAP_FMAC6 __wsdd__ProbeMatches(struct soap*, struct wsdd__ProbeMatchesType *wsdd__ProbeMatches) { return 0; }
SOAP_FMAC5 int SOAP_FMAC6 __wsdd__Resolve(struct soap*, struct wsdd__ResolveType *wsdd__Resolve) { return 0; }
SOAP_FMAC5 int SOAP_FMAC6 __wsdd__ResolveMatches(struct soap*, struct wsdd__ResolveMatchesType *wsdd__ResolveMatches) { return 0; }
SOAP_FMAC5 int SOAP_FMAC6 __tdn__Hello(struct soap*, struct wsdd__HelloType tdn__Hello, struct wsdd__ResolveType &tdn__HelloResponse) { return 0; }
SOAP_FMAC5 int SOAP_FMAC6 __tdn__Bye(struct soap*, struct wsdd__ByeType tdn__Bye, struct wsdd__ResolveType &tdn__ByeResponse) { return 0; }
SOAP_FMAC5 int SOAP_FMAC6 __tdn__Probe(struct soap*, struct wsdd__ProbeType tdn__Probe, struct wsdd__ProbeMatchesType &tdn__ProbeResponse) { return 0; }
int main()
{
// 设置网络地址
struct soap *serv = soap_new1(SOAP_IO_UDP);
serv->bind_flags = SO_REUSEADDR;
if (!soap_valid_socket(soap_bind(serv, NULL, 3702, 1000))) {
soap_print_fault(serv, stderr);
printf("group membership failed:%s\n", strerror(errno));
getchar();
exit(1);
}
ip_mreq mcast;
mcast.imr_multiaddr.s_addr = inet_addr("239.255.255.250");
mcast.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(serv->master, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mcast, sizeof(mcast)) < 0) {
getchar();
exit(1);
}
// 启动服务
soap_serve(serv);
}