本文共 5282 字,大约阅读时间需要 17 分钟。
用gSOAP实现一个简单四则运算的服务器及代理。
Table of Contents
试着用gSOAP实现一个简单四则运算的服务器代码,给出
//gsoap ns service name: calc Simple calculator service //gsoap ns service style: rpc //gsoap ns service encoding: encoded //gsoap ns service namespace: http://localhost/calc.wsdl //gsoap ns service location: http://localhost/server.cgi //gsoap ns schema namespace: urn:calc //gsoap ns service method: add Sums two valuesint ns__add(double a, double b, double *result);//gsoap ns service method: sub Subtracts two valuesint ns__sub(double a, double b, double *result);//gsoap ns service method: mul Multiplies two valuesint ns__mul(double a, double b, double *result);//gsoap ns service method: div Divides two valuesint ns__div(double a, double b, double *result);//gsoap ns service method: pow Raises a to bint ns__pow(double a, double b, double *result);
注意ns__add中的“__”为双下划线。
也可通过使用wsdl文件通过wsdl2h指令生成头文件,如下:
wsdl2h用作wsdl和.h文件的转换。soapcpp2用头文件生成客户端/服务端等开发需要的h和cpp文件。经常使用的一些指令如下: -o filename.h 将wsdl转化为filename.h头文件。 -s 不生成STL代码 -c 生成纯C风格的头文件,这将去除C++的一些特性 -n name 使用name代替默认前缀ns -t filename.dat 使用filename.dat代替默认的typemap.dat文件 -zX 兼容之前的X版本
然后通过使用soapcpp2指令生成对应的soap代理代码,soapcpp2的常用选项和使用方法如下:
wsdl2h用作wsdl和.h文件的转换。soapcpp2用头文件生成客户端/服务端等开发需要的h和cpp文件。 经常使用的一些指令如下: -i 生成server的proxy和object,这种object继承于soap struct。 -j 和-i类似,区别在于生成的代理类不继承于soap struct,而是包含了包含了一个soap结构的指针。此种方式生存的代理类便于互相通信 -C 仅生成客户端client代码 -S 仅生成服务端server代码 -x 不生成xml文件。不用此项的话,将对头文件中定义的每个operation生成一个描述性的xml文件 -L 不生成soapClientLib文件和soapServerLib文件 -p name 修改文件名前缀,代替soap -q name 指定代理类和对象使用的名空间name,包含文件名前缀
可以分别通过
soapcpp2 -S -i calc.h
和
soapcpp2 -C -i calc.h
生成服务端和客户端(代理)程序soapcalcService.cpp,soapcalcProxy.cpp。
HDR_CALC:=calc.hSRC_SERVER:=calcServer.ccSRC_CLIENT:=calcClient.ccSOAP_SRV:=soapC.cpp soapcalcService.cppSOAP_CLT:=soapC.cpp soapcalcProxy.cppLIBS:=-lgsoap++all: server client#-i : 生成从soap结构继承的C ++服务代理和对象。${SOAP_SRV}:${HDR_CALC} soapcpp2 -S -i ${HDR_CALC} ${SOAP_CLT}:${HDR_CALC} soapcpp2 -C -i ${HDR_CALC}client:${HDR_CALC} ${SOAP_CLT} g++ -o client ${SRC_CLIENT} ${SOAP_CLT} ${LIBS}server:${HDR_CALC} ${SOAP_SRV} g++ -o server ${SRC_SERVER} ${SOAP_SRV} ${LIBS}clean: rm -rf client server *.xml *.nsmap soap*
#include "soapcalcService.h"#include "calc.nsmap"int main(int argc, char **argv){ calcService calc; if(argc < 2) { fprintf(stderr, "Usage: calcserver++\n"); exit(0); } if (argc < 2) calc.serve(); /* serve as CGI application */ else { int port = atoi(argv[1]); if (!port) { fprintf(stderr, "Usage: calcserver++ \n"); exit(0); } /* run iterative server on port until fatal error */ if (calc.run(port)) { calc.soap_stream_fault(std::cerr); exit(-1); } } return 0;} int calcService::add(double a, double b, double *result){ *result = a + b; return SOAP_OK;} int calcService::sub(double a, double b, double *result){ *result = a - b; return SOAP_OK;} int calcService::mul(double a, double b, double *result){ *result = a * b; return SOAP_OK;} int calcService::div(double a, double b, double *result){ if (b) *result = a / b; else { char *s = (char*)soap_malloc(this, 1024); // (SOAP_SNPRINTF(s, 1024, 100), " Can't divide %f by %f ", a, b); snprintf(s, 1024, "Can't divide %f by %f ", a, b); return soap_senderfault("Division by zero", s); } return SOAP_OK;} int calcService::pow(double a, double b, double *result){ *result = ::pow(a, b); if (soap_errno == EDOM) /* soap_errno is like errno, but compatible with Win32 */ { char *s = (char*)soap_malloc(this, 1024); // (SOAP_SNPRINTF(s, 1024, 100), "Can't take power of %f to %f ", a, b); snprintf(s, 1024, "Can't take power of %f to %f ", a, b); return soap_senderfault("Power function domain error", s); } return SOAP_OK;}
#include "soapcalcProxy.h"#include "calc.nsmap"char server[256] = "http://127.0.0.1:";int main(int argc, char **argv){ if (argc < 5) { fprintf(stderr, "Usage: [add|sub|mul|div|pow] num num port\n"); exit(0); } double a, b, result; a = strtod(argv[2], NULL); b = strtod(argv[3], NULL); calcProxy calc; strcat(server, argv[4]); calc.soap_endpoint = server; switch (*argv[1]) { case 'a': calc.add(a, b, &result); break; case 's': calc.sub(a, b, &result); break; case 'm': calc.mul(a, b, &result); break; case 'd': calc.div(a, b, &result); break; case 'p': calc.pow(a, b, &result); break; default: fprintf(stderr, "Unknown command\n"); exit(0); } if (calc.error) calc.soap_stream_fault(std::cerr); else printf("result = %g\n", result); return 0;}
一个终端:$ ./server 121212另一个终端:$ ./client add 123 234 121212result = 357
转载地址:http://dypaf.baihongyu.com/