博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【gSOAP】gSOAP生成服务代理和对象C语言代码示例
阅读量:2029 次
发布时间:2019-04-28

本文共 5282 字,大约阅读时间需要 17 分钟。

用gSOAP实现一个简单四则运算的服务器及代理。

Table of Contents


试着用gSOAP实现一个简单四则运算的服务器代码,给出

头文件

编写头文件calc.h

//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中的“__”为双下划线。

生成头文件calc.h

也可通过使用wsdl文件通过wsdl2h指令生成头文件,如下:

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的常用选项和使用方法如下:

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。

完整的makefile

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*

客户端&服务端代码

服务端代码calcServer.cc

#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;}

客户端代码calcClient.cc

#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/

你可能感兴趣的文章
Java serialVersionUID 有什么作用?
查看>>
Java中的关键字 transient
查看>>
transient在java中的作用
查看>>
Java 利用枚举实现单例模式
查看>>
Java—Object对象和Collection对象的toString()方法
查看>>
Java数组的三种打印方式
查看>>
Lists.newArrayList
查看>>
Arrays.asList和Lists.newList使用时的陷阱
查看>>
Java集合和数组的区别
查看>>
快速理解java泛型用法
查看>>
部分版本Oracle多层嵌套查询不识别列名的BUG
查看>>
Java泛型的学习和使用
查看>>
代码整洁之道——最佳实践小结
查看>>
代码整洁 vs 代码肮脏
查看>>
svn更新失败提示cleanup的解决方法
查看>>
SecureCRT中文乱码问题的解决
查看>>
java rmi 使用教程【一】
查看>>
java rmi 使用教程【二】
查看>>
java rmi 使用教程【三】
查看>>
java RMI原理
查看>>