我把例程里面的README.txt翻译了一下
程序也就一目了然了,但是因为makefile是automake生成的,那部分还每搞清楚。
Simple calculator service implements:
add(a,b)
sub(a,b)
mul(a,b)
div(a,b)
pow(a,b)
Compilation in C (see samples/calc):
soapcpp2 -c calc.h
cc -o calcclient calcclient.c stdsoap2.c soapC.c soapClient.c
cc -o calcserver calcserver.c stdsoap2.c soapC.c soapServer.c
For C++ development soapcpp2 option -i generates proxy and service classes,
which encapsulate the method operations in the class instead of defining them
as global functions as in C.
The calcclient application invokes the service and is used from the command
line as follows:
$ calcclient add 3 4-
result = 7
calcserver 应用程序是一个CGI(公共网关接口)应用程序可以在你的web 服务目录下建立
C语言的客户端用到了:
初始化运行引擎:
soap_init(struct soap*)
调用XYZ,这个函数是soapcpp2生成的:
soap_call_ns__xyz(struct soap*, const char *endpoint, const char *action,
double a, double b, double *result)
Note: endpoint=NULL and action=NULL for defaults
打印通信错误:
soap_print_fault(struct soap*, FILE*)
分配数据,保持可用状态(alive)指导被soap_end释放
soap_malloc(struct soap*, size_t len)
删除反序列数据
soap_end(struct soap*)
完成和分离运行引擎
soap_done(struct soap*)
C语言服务器端用到:
初始化运行引擎
soap_init(struct soap*)
绑定端口:
soap_bind(struct soap*, const char *host, int port, int backlog)
接收一个请求:
soap_accept(struct soap*);
调用服务调度程序,这个函数是soapcpp2生成的
soap_serve(struct soap*)
打印通信错误
soap_print_fault(struct soap*, FILE*)
分配数据,保持可用状态(alive)指导被soap_end释放
soap_malloc(struct soap*, size_t len)
删除反序列数据
soap_end(struct soap*)
发回sender-related 错误
soap_sender_fault(struct soap*, const char *string, const char *detailXML)
发回receiver-related错误
soap_receiver_fault(struct soap*, const char *string, const char *detailXML)
完成和分离运行引擎
soap_done(struct soap*)
服务操作不是自动生成的(使用已定义的)
ns__add(struct soap*, double a, double b, double *result)
ns__sub(struct soap*, double a, double b, double *result)
ns__mul(struct soap*, double a, double b, double *result)
ns__div(struct soap*, double a, double b, double *result)
ns__pow(struct soap*, double a, double b, double *result)
calc.h
//gsoap ns service name: calc Simple calculator service described at http://www.genivia.com/dev.html //gsoap ns service protocol: SOAP //gsoap ns service style: rpc //gsoap ns service encoding: encoded //gsoap ns service namespace: http://websrv.cs.fsu.edu/~engelen/calc.wsdl //gsoap ns service location: http://websrv.cs.fsu.edu/~engelen/calcserver.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);
#include "soapH.h" #include "calc.nsmap" const char server[] = "http://websrv.cs.fsu.edu/~engelen/calcserver.cgi"; /* = "http://localhost:8080"; to test against samples/webserver */ int main(int argc, char **argv) { struct soap soap; double a, b, result; if (argc < 4) { fprintf(stderr, "Usage: [add|sub|mul|div|pow] num num\n"); exit(0); } soap_init1(&soap, SOAP_XML_INDENT); a = strtod(argv[2], NULL); b = strtod(argv[3], NULL); switch (*argv[1]) { case 'a': soap_call_ns__add(&soap, server, "", a, b, &result); break; case 's': soap_call_ns__sub(&soap, server, "", a, b, &result); break; case 'm': soap_call_ns__mul(&soap, server, "", a, b, &result); break; case 'd': soap_call_ns__div(&soap, server, "", a, b, &result); break; case 'p': soap_call_ns__pow(&soap, server, "", a, b, &result); break; default: fprintf(stderr, "Unknown command\n"); exit(0); } if (soap.error) { soap_print_fault(&soap, stderr); exit(1); } else printf("result = %g\n", result); soap_destroy(&soap); soap_end(&soap); soap_done(&soap); return 0; }
#include "soapH.h" #include "calc.nsmap" int main(int argc, char **argv) { SOAP_SOCKET m, s; /* master and slave sockets */ struct soap soap; soap_init(&soap); if (argc < 2) soap_serve(&soap); /* serve as CGI application */ else { m = soap_bind(&soap, NULL, atoi(argv[1]), 100); if (!soap_valid_socket(m)) { soap_print_fault(&soap, stderr); exit(-1); } fprintf(stderr, "Socket connection successful: master socket = %d\n", m); for ( ; ; ) { s = soap_accept(&soap); fprintf(stderr, "Socket connection successful: slave socket = %d\n", s); if (!soap_valid_socket(s)) { soap_print_fault(&soap, stderr); exit(-1); } soap_serve(&soap); soap_end(&soap); } } return 0; } int ns__add(struct soap *soap, double a, double b, double *result) { (void)soap; *result = a + b; return SOAP_OK; } int ns__sub(struct soap *soap, double a, double b, double *result) { (void)soap; *result = a - b; return SOAP_OK; } int ns__mul(struct soap *soap, double a, double b, double *result) { (void)soap; *result = a * b; return SOAP_OK; } int ns__div(struct soap *soap, double a, double b, double *result) { if (b) *result = a / b; else { char *s = (char*)soap_malloc(soap, 1024); (SOAP_SNPRINTF(s, 1024, 100), "<error xmlns=\"http://tempuri.org/\">Can't divide %f by %f</error>", a, b); return soap_sender_fault(soap, "Division by zero", s); } return SOAP_OK; } int ns__pow(struct soap *soap, 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(soap, 1024); (SOAP_SNPRINTF(s, 1024, 100), "<error xmlns=\"http://tempuri.org/\">Can't raise %f to %f</error>", a, b); return soap_sender_fault(soap, "Power function domain error", s); } return SOAP_OK; }