wed services SOAP调用实例
2015-12-29 13:41
211 查看
此博文仅限于自己参考使用,描述不恰当之处请见谅
编写头文件:add.h
在这里我们不需要wsdl的文件,可以直接从.h文件来生成代码其生成的.h并不能直接用,是被soapcpp2用来解释生成soap框架代码的。我们定义一个函数声明文件,用来定义接口函数,名称为add.h
#ifndef _ADDH_
#define _ADDH_
int ns2_add(int num1,int num2,int *sum);
#endif
3、产生代码框架
我们执行一下命令,自动生成一些远程调用需要的文件。
拷贝 /home/qinyisong/gsoap_x386/bin/soapcpp2到所需文件夹
soapcpp2 -c add.h -I /home/qinyisong/gsoap_x386/share/gsoap/import/ -I /home/qinyisong/gsoap_x386/share/gsoap/custom/
-c是产生纯C代码,如果提示找不到typemap.dat,将gsoap/下的typemap.dat复制到当前目录就可以了。通过上列命令我们会得到如下文件: soapH.h soapC.c soap.nsmap soapClient.c soapServer.c soapClientLib.c soapServerLib. soapStub.h
soapH.h soap.c中函数及数据声明,同时包含stdsoap.h头文件,客户端和服务器都会用到。
soapC.c 客户端和服务器都会用到,soap通信协议的解析和编码函数,使用soapH.h,其实核心文件。
soap.nsmap xsi、xsd等命名空间
soapClient.c 客户端使用, 有关于远程调用服务器功能的函数实现
soapServer.c 服务器使用,有关于服务器被调用实现函数
soapClientLib.c soapServerLib 用来生成更上层的client和server的封装库,无用
soapStub.h 服务器和客户端都用,根据用户头文件生成的soap通信协议数据结构定义以及soap操作服务和客户端的函数。
stdsoap2.h soap的基础函数头文件
stdsoap2.c soap的基础函数比如soap初始化,soap的结构体堆分配以及各种设置函数等等
stdsoap2.c stdsoap2.h 必须拷贝到文件夹,不用生成,此文件实现soap的通信基础函数和数据类型,是实现soap的底层网络通信http等函数,与onvif.h无关
先大概记住他们的名字,将来会提到他们。
4、添加服务端代码,创建文件:addserver.c
#include "soapH.h"
#include "soap.nsmap"
int main(int argc,char **argv)
{
int m,s;
struct soap add_soap;
soap_init(&add_soap);
soap_set_namespaces(&add_soap,namespaces);
if (argc<2)
{
printf("usage:%s<server_port>\n",argv[0]);
exit(1);
}
else
{
m=soap_bind(&add_soap,NULL,atoi(argv[1]),100);
if(m<0)
{
soap_print_fault(&add_soap,stderr);
exit(-1);
}
fprintf(stderr,"Socketconnectionsuccessful:mastersocket=%d\n",m);
for(;;)
{
s=soap_accept(&add_soap);
if (s<0)
{
soap_print_fault(&add_soap,stderr);
exit(-1);
}
fprintf(stderr,"Socketconnectionsuccessful:slavesocket=%d\n",s);
soap_serve(&add_soap);
soap_end(&add_soap);
}
}
return 0;
}
#if 1
int ns2_add(struct soap *add_soap,int num1,int num2,int *sum)
{
*sum=num1+num2;
return 0;
}
#endif
5、添加客户端代码,创建文件:addclient.c
#include "soapStub.h"
#include "soap.nsmap"
int add(const char *server,int num1,int num2,int *sum)
{
struct soap add_soap;
int result=0;
soap_init(&add_soap);
soap_set_namespaces(&add_soap,namespaces);
soap_call_ns2_add(&add_soap,server,NULL,num1,num2,sum);
printf("serveris%s,num1is%d,num2is%d/n",server,num1,num2);
if (add_soap.error)
{
printf("soaperror:%d,%s,%s\n",add_soap.error,*soap_faultcode(&add_soap),*soap_faultstring(&add_soap));
result=add_soap.error;
}
soap_end(&add_soap);
soap_done(&add_soap);
return result;
}
6、写客户端测试代码,创建文件:client_test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int add(const char *server,int num1,int num2,int *sum);
int main(int argc,char **argv)
{
int result=-1;
char server[128]={0};
int num1;
int num2;
int sum;
if(argc<4)
{
printf("usage:%s<ip:port>num1num2\n",argv[0]);
exit(1);
}
strcpy(server,argv[1]);
num1=atoi(argv[2]);
num2=atoi(argv[3]);
result=add(server,num1,num2,&sum);
if(result!=0)
{
printf("soaperror,errcode=%d\n",result);
}
else
{
printf("%d+%d=%d\n",num1,num2,sum);
}
return 0;
}
7、编写Makefile,编译前,先将gsoap-2.8\gsoap目录下的stdsoap2.c和stdsoap2.h复制到当前目录下,它提供了对SOAP协议的简单调用。
GSOAP_ROOT = /home/qinyisong/gsoap_x386/share/gsoap
CC = gcc -g -DWITH_NONAMESPACES
INCLUDE = -I$(GSOAP_ROOT)
SERVER_OBJS = soapC.o stdsoap2.o soapServer.o addserver.o
CLIENT_OBJS = soapC.o stdsoap2.o soapClient.o addclient.o client_test.o
#make default
all:server
#make server
server:$(SERVER_OBJS)
$(CC) $(INCLUDE) -o addserver $(SERVER_OBJS)
#make client
client:$(CLIENT_OBJS)
$(CC) $(INCLUDE) -o client_test $(CLIENT_OBJS)
clean:
rm -f *.o client_test
8、编译服务端make server,编译客户端make client 得到addserver和client_test
9、测试
一个最简单的soap调用的例子完成了。
下面我们来分析上面的例子,刚才我们只是创建一个add.h头文件,在add.h头文件中声明了一个函数:
[cpp] view
plaincopy
int ns2__add( int num1, int num2, int* sum );
其他所有的的代码都是一句他来生成的。那么这个的实体在哪?对,就是在需要我们自己添加的addserver.c中:
但是它好像多了一个struct soap类型的参数,这是soap全局运行环境,所有的函数都第一个包含这个参数。注意上面的Makefile,不管是编译server还是编译client都是没有用到刚才的add.h文件的。ns2__add真正的声明在自动产生的soapStub.h中
然后在自动产生的soapServer.c中被soap_serve_ns2__add()函数调用。这样,就将真正的加法运算的ns2__add函数和soap代码框架联系了起来。那么,在客户端的代码中又是怎样来调用这个远程函数的呢?
客户端代码
在刚才添加的addtest.c中main函数中调用一个简单的add函数
这个函数的实现也是我们自己添加的,在addclient.c中:
这个函数有些复杂,因为它把客户端的调用和soap联系了起来,还记得吗,我们编译server和client的时候复制了两个文件stdsoap2.h和stdsoap2.c,这里面的soap_init() soap_end()等函数来自他们。stdsoap2提供了soap协议的简单操作,之需要简单的函数调用就能完成远程的函数调用。注意soap_call_ns2__add(),它同样在soapStub.h中声明,只不过是Client-Side Call
Stubs,不明白stub意思的可以搜索rpc
这个函数的实现在自动产生的soapClient.c源文件中。同样不需要我们实现。
这样就可以通过调用gSOAP提供的stdsoap2的soap_init和自动产生的soap_call_ns2__add就实现了远程主机上的ns2__add函数的调用
编写头文件:add.h
在这里我们不需要wsdl的文件,可以直接从.h文件来生成代码其生成的.h并不能直接用,是被soapcpp2用来解释生成soap框架代码的。我们定义一个函数声明文件,用来定义接口函数,名称为add.h
#ifndef _ADDH_
#define _ADDH_
int ns2_add(int num1,int num2,int *sum);
#endif
3、产生代码框架
我们执行一下命令,自动生成一些远程调用需要的文件。
拷贝 /home/qinyisong/gsoap_x386/bin/soapcpp2到所需文件夹
soapcpp2 -c add.h -I /home/qinyisong/gsoap_x386/share/gsoap/import/ -I /home/qinyisong/gsoap_x386/share/gsoap/custom/
-c是产生纯C代码,如果提示找不到typemap.dat,将gsoap/下的typemap.dat复制到当前目录就可以了。通过上列命令我们会得到如下文件: soapH.h soapC.c soap.nsmap soapClient.c soapServer.c soapClientLib.c soapServerLib. soapStub.h
soapH.h soap.c中函数及数据声明,同时包含stdsoap.h头文件,客户端和服务器都会用到。
soapC.c 客户端和服务器都会用到,soap通信协议的解析和编码函数,使用soapH.h,其实核心文件。
soap.nsmap xsi、xsd等命名空间
soapClient.c 客户端使用, 有关于远程调用服务器功能的函数实现
soapServer.c 服务器使用,有关于服务器被调用实现函数
soapClientLib.c soapServerLib 用来生成更上层的client和server的封装库,无用
soapStub.h 服务器和客户端都用,根据用户头文件生成的soap通信协议数据结构定义以及soap操作服务和客户端的函数。
stdsoap2.h soap的基础函数头文件
stdsoap2.c soap的基础函数比如soap初始化,soap的结构体堆分配以及各种设置函数等等
stdsoap2.c stdsoap2.h 必须拷贝到文件夹,不用生成,此文件实现soap的通信基础函数和数据类型,是实现soap的底层网络通信http等函数,与onvif.h无关
先大概记住他们的名字,将来会提到他们。
4、添加服务端代码,创建文件:addserver.c
#include "soapH.h"
#include "soap.nsmap"
int main(int argc,char **argv)
{
int m,s;
struct soap add_soap;
soap_init(&add_soap);
soap_set_namespaces(&add_soap,namespaces);
if (argc<2)
{
printf("usage:%s<server_port>\n",argv[0]);
exit(1);
}
else
{
m=soap_bind(&add_soap,NULL,atoi(argv[1]),100);
if(m<0)
{
soap_print_fault(&add_soap,stderr);
exit(-1);
}
fprintf(stderr,"Socketconnectionsuccessful:mastersocket=%d\n",m);
for(;;)
{
s=soap_accept(&add_soap);
if (s<0)
{
soap_print_fault(&add_soap,stderr);
exit(-1);
}
fprintf(stderr,"Socketconnectionsuccessful:slavesocket=%d\n",s);
soap_serve(&add_soap);
soap_end(&add_soap);
}
}
return 0;
}
#if 1
int ns2_add(struct soap *add_soap,int num1,int num2,int *sum)
{
*sum=num1+num2;
return 0;
}
#endif
5、添加客户端代码,创建文件:addclient.c
#include "soapStub.h"
#include "soap.nsmap"
int add(const char *server,int num1,int num2,int *sum)
{
struct soap add_soap;
int result=0;
soap_init(&add_soap);
soap_set_namespaces(&add_soap,namespaces);
soap_call_ns2_add(&add_soap,server,NULL,num1,num2,sum);
printf("serveris%s,num1is%d,num2is%d/n",server,num1,num2);
if (add_soap.error)
{
printf("soaperror:%d,%s,%s\n",add_soap.error,*soap_faultcode(&add_soap),*soap_faultstring(&add_soap));
result=add_soap.error;
}
soap_end(&add_soap);
soap_done(&add_soap);
return result;
}
6、写客户端测试代码,创建文件:client_test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int add(const char *server,int num1,int num2,int *sum);
int main(int argc,char **argv)
{
int result=-1;
char server[128]={0};
int num1;
int num2;
int sum;
if(argc<4)
{
printf("usage:%s<ip:port>num1num2\n",argv[0]);
exit(1);
}
strcpy(server,argv[1]);
num1=atoi(argv[2]);
num2=atoi(argv[3]);
result=add(server,num1,num2,&sum);
if(result!=0)
{
printf("soaperror,errcode=%d\n",result);
}
else
{
printf("%d+%d=%d\n",num1,num2,sum);
}
return 0;
}
7、编写Makefile,编译前,先将gsoap-2.8\gsoap目录下的stdsoap2.c和stdsoap2.h复制到当前目录下,它提供了对SOAP协议的简单调用。
GSOAP_ROOT = /home/qinyisong/gsoap_x386/share/gsoap
CC = gcc -g -DWITH_NONAMESPACES
INCLUDE = -I$(GSOAP_ROOT)
SERVER_OBJS = soapC.o stdsoap2.o soapServer.o addserver.o
CLIENT_OBJS = soapC.o stdsoap2.o soapClient.o addclient.o client_test.o
#make default
all:server
#make server
server:$(SERVER_OBJS)
$(CC) $(INCLUDE) -o addserver $(SERVER_OBJS)
#make client
client:$(CLIENT_OBJS)
$(CC) $(INCLUDE) -o client_test $(CLIENT_OBJS)
clean:
rm -f *.o client_test
8、编译服务端make server,编译客户端make client 得到addserver和client_test
9、测试
一个最简单的soap调用的例子完成了。
实例分析
服务端代码下面我们来分析上面的例子,刚才我们只是创建一个add.h头文件,在add.h头文件中声明了一个函数:
[cpp] view
plaincopy
int ns2__add( int num1, int num2, int* sum );
其他所有的的代码都是一句他来生成的。那么这个的实体在哪?对,就是在需要我们自己添加的addserver.c中:
但是它好像多了一个struct soap类型的参数,这是soap全局运行环境,所有的函数都第一个包含这个参数。注意上面的Makefile,不管是编译server还是编译client都是没有用到刚才的add.h文件的。ns2__add真正的声明在自动产生的soapStub.h中
然后在自动产生的soapServer.c中被soap_serve_ns2__add()函数调用。这样,就将真正的加法运算的ns2__add函数和soap代码框架联系了起来。那么,在客户端的代码中又是怎样来调用这个远程函数的呢?
客户端代码
在刚才添加的addtest.c中main函数中调用一个简单的add函数
这个函数的实现也是我们自己添加的,在addclient.c中:
这个函数有些复杂,因为它把客户端的调用和soap联系了起来,还记得吗,我们编译server和client的时候复制了两个文件stdsoap2.h和stdsoap2.c,这里面的soap_init() soap_end()等函数来自他们。stdsoap2提供了soap协议的简单操作,之需要简单的函数调用就能完成远程的函数调用。注意soap_call_ns2__add(),它同样在soapStub.h中声明,只不过是Client-Side Call
Stubs,不明白stub意思的可以搜索rpc
这个函数的实现在自动产生的soapClient.c源文件中。同样不需要我们实现。
这样就可以通过调用gSOAP提供的stdsoap2的soap_init和自动产生的soap_call_ns2__add就实现了远程主机上的ns2__add函数的调用
相关文章推荐
- 消灭星星山寨版-我代表星星消灭你
- JSP页面显示含有中文名称(中文路径)出错?
- Mac磁盘修复
- 参数大对象定义与传递
- ObjC 利用反射和KVC实现嵌套对象序列化成JSON数据
- 改变tableviewcell分割线的长度
- 关于说话
- Xcode 同一个项目多个target
- 利用pgpool实现PostgreSQL的高可用
- IOS8 H264硬件解码
- windows 7 64位 Apache httpd 最新包的安装
- VirtualBox Centos 网络设置
- 伪类
- wave文件格式分析
- BlueJ的code pad
- 1、c#对XML文件的解析
- 17.cocos2d-x网络编程三(SocketIO)
- 找色块--小游戏
- iOS第三方数据库FMDB的使用介绍
- 实习心得