Gsoap的安装和使用教程:http://blog.163.com/wupengzhi2005@126/blog/static/17101002201072121336803/
下面是我自己写的一些.c、头文件
对于像我这样的菜鸟在学习新工具或者新lib的时候,可能刚开始的时候特别怕这些东西,老大要求你在规定时间内把这个新技术学到手或者让你写一个东西出来,不要怕!其实大部分工具和软件在安装的时候都是有实例的,比如gsoap,在安装目录下有一个samples/目录,里面有c/c++对应的实例,你只需要按照他们给的例子稍微修改一下,明白实例中给的最基本的接口,就算是完成初步的学习了,接下来要学习更高级的接口,只需要静下心来,一步一步的看下去就ok了!
一、定义函数接口,写.h文件
/***********************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://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-documentation: add Sums two values
int add(int a, int b, int *result);
//gsoap ns service method-documentation: sub Subtracts two values
int sub(int a, int b, int *result);
二、根据.h文件生成gsoap project
soapcpp2 -c calc.h(c参数为生成c代码,不带c参数默认生成c++代码),如果感觉生成的文件太多太乱,可以加x参数,不生成xml文件(对执行文件的生成无影响)。
生成的文件其中比较重要的有:soapC.c soapServer.c soapClient.c stdsoap2.c (后两个需要到~/gsoap-2.7/gsoap/目录下去cp到当前目录下),这几个文件使我们编译生成可执行性文件的时候需要的文件。
当然其他的文件也很重要,在实现函数的时候尤其需要注意的是soapStub.h,这个.h中声明了我们之前定义定义的函数接口在gsoap应用中的函数接口,我们在服务端定义我们的函数,在客户端如何调用远程服务端定义的函数,如:在cacl.h中,我们最初声明的函数为:int add(int a, int b, int *result);
我们可以在soapStub.h中找到我们在服务端实现的这个函数声明:SOAP_FMAC5 int SOAP_FMAC6 ns__add(struct soap*, int a, int b, int *result);
我们在客户端调用add函数的函数声明为:SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns__add(struct soap *soap, const char *soap_endpoint, const char *soap_action, int a, int b, int *result);
(第二个参数我目前理解为端口或者客户端访问服务端的一个入口或者地址吧)
三、服务器端函数功能的实现和main函数的编写
这是我自己的huaServer.c函数
#include <stdio.h>
#include "soapH.h"
#include "calc.nsmap"
int main(int argc, char *argv[])
{
struct soap soap;
SOAP_SOCKET m, s;
int ret;
soap_init(&soap);
if (argc < 2)
soap_serve(&soap);
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, int a, int b, int *result)
{
*result = a + b;
return SOAP_OK;
}
int ns__sub(struct soap *soap, int a, int b, int *result)
{
*result = a - b;
return SOAP_OK;
}
其实这个代码跟源文件中给出的例子非常相近,就不在多说,主要说一下需要注意的几点:
1.main函数的框架:大体就是`soap_init->soap_bind->while(1){soap_accept}->soap_serve->soap_end,根socket的用法大体一样,初始化,绑定(传入的argv[1]即为要监听的端口号),监听接收,释放。
2.看到了吗,我们add和sub函数的实现,就是前面soapStub.h中给我们的函数声明一样,如果不这样写的话,编译是会报错的。需要注意的主要是这两点,复杂的东西,你自己往里面填充就可以了。
四、服务器端编译
我们这里只有这一个我们自己写的.c文件,按照下面的命令编译即可得到我们可执行文件huaServer 了
gcc -o huaServer huaServer.c stdsoap2.c soapC.c soapServer.c
执行的时候记得加上端口号 比如 8888
五、客户端main函数的编写和服务器端功能的调用
这是我的huaClient.c
#include "soapH.h"
#include "calc.nsmap"
const char server[] = "http://localhost:8888";
int main(int argc, char *argv[])
{
struct soap soap;
int a, b, result;
if (argc < 4)
{
fprintf(stderr, "Usage: [add|sub|mul|div|pow] num num\n");
exit(0);
}
a = atoi(argv[2]);
b = atoi(argv[3]);
soap_init(&soap);
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;
default:
fprintf(stderr, "Unknown command\n");
exit(0);
}
if (soap.error)
{
soap_print_fault(&soap, stderr);
exit(1);
}
else
printf("result = %d\n", result);
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
return 0;
}
由于客户端跟服务端一般不在同一台机器上,我们是没有服务端的环境的,比如我们前面提到的soapC.c soapClient.c stdsoap2.c stdsoap2.h soapStub.h等。我们可能只是建了一个客户端的目录,里面什么都没有的,那这些文件是怎么生成的呢,这里我们便用到了我们在服务器端用soapcpp2命令生成的后缀名为wsdl的一个文件,这个文件———
框架一目了然:初始化->调用远程函数->释放
注意到了吗,调用远程函数用的是这个:soap_call_ns__add(&soap, server, "", a, b, &result);
是不是跟我们前面提到的soapStub.h中给客户端调用的函数声明SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns__add(struct soap *soap, const char *soap_endpoint, const char *soap_action, int a, int b, int *result);
是一样的呢?
六、编译客户端
gcc -o huaServer hua.c stdsoap2.c soapC.c soapServer.c
ok,编译好了之后,我们便可以执行试一下了!
perfect!!
可能有很多跟我一样的菜鸟是第一次用gsoap这个东西,学习新东西,不动手怎么行!!相信你自己动手写了这个小程序之后,必定对gsoap有了新的认识,以后写复杂的东西也肯定更有信心了。