【gSOAP】gSOAP生成服务代理和对象C语言代码示例

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

Table of Contents

头文件

编写头文件calc.h

生成头文件calc.h

wsdl2h使用方法

生成服务端和客户端(代理)程序

soapcpp2使用方法

完整的makefile

客户端&服务端代码

服务端代码calcServer.cc

客户端代码calcClient.cc

运行

整体流程


试着用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 values
int ns__add(double a, double b, double *result);

//gsoap ns service method: sub Subtracts two values
int ns__sub(double a, double b, double *result);

//gsoap ns service method: mul Multiplies two values
int ns__mul(double a, double b, double *result);

//gsoap ns service method: div Divides two values
int ns__div(double a, double b, double *result);

//gsoap ns service method: pow Raises a to b
int 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.h
SRC_SERVER:=calcServer.cc
SRC_CLIENT:=calcClient.cc


SOAP_SRV:=soapC.cpp soapcalcService.cpp
SOAP_CLT:=soapC.cpp soapcalcProxy.cpp

LIBS:=-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++ <port>\n");
        exit(0);
    }

    if (argc < 2)
        calc.serve();   /* serve as CGI application */
    else
    { 
        int port = atoi(argv[1]);
        if (!port)
        { 
            fprintf(stderr, "Usage: calcserver++ <port>\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), "<error xmlns=\"http://tempuri.org/\">Can't divide %f by %f</error>", a, b);
        snprintf(s, 1024, "<error xmlns=\"http://tempuri.org/\">Can't divide %f by %f</error>", 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), "<error xmlns=\"http://tempuri.org/\">Can't take power of %f to %f</error>", a, b);
        snprintf(s, 1024, "<error xmlns=\"http://tempuri.org/\">Can't take power of %f to %f</error>", 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 121212
result = 357

整体流程

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页