Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
Linux 下 gsoap 的使用及移植
1、 下载 gsoap
在 gsoap 的官网中可以找到最新的 gsoap 安装包及相关文档
gsoap 官网:http://www.cs.fsu.edu/~engelen/soap.html
下载地址:http://sourceforge.net/projects/gsoap2/files/
2、 安装 gsoap
a、 解压 zip 压缩包
命令:unzip gsoap_2.8.1.zip
b、 进入解压后生成的文件夹 gsoap-2.8
命令:cd gsoap-2.8/
c、 切换到 root 用户
命令:su
输入密码
d、 配置编译环境
在 gsoap-2.8/文件夹下执行 configure 文件,自动配置编译环境
命令:./configure
e、 编译连接
命令:make
f、 安装 gsoap
命令:make install
安装完毕可用 wsdl2h 或 soapcpp2 查看 gsoap 是否已经安装成功
看到上述两个命令的返回说明安装成功
3、 应用实例
wsdl2h -o outfile.h infile.wsdl 实现 wsdl 文件到 h 文件的数据映射
soapcpp2 -c outfile.h 生成相应的底层通信 stub,strech 程序
首先新建一个文件夹名为 gsoap;然后
(1) 不使用 wsdl2h
a、 不使用 wsdl2h 我们可以直接从.h 文件来生成代码。我们先定义一个函数声明文
件,用来定义接口函数,名称为 add.h,内容如下:
//gsoapopt cw
//gsoap ns2 schema namespace: urn:add
//gsoap ns2 schema form: unqualified
//gsoap ns2 service name: add
//gsoap ns2 service type: addPortType
//gsoap ns2 service port:http://websrv.cs.fsu.edu/~engelen/addserver.cgi
//gsoap ns2 service namespace: urn:add
//gsoap ns2 service transport: http://schemas.xmlsoap.org/soap/http
//gsoap ns2 service method-style: add rpc
//gsoap ns2 service method-encoding:
add http://schemas.xmlsoap.org/soap/encoding/
//gsoap ns2 service method-action: add ""
int ns2__add( int num1, int num2, int* sum );
b、 执行 soapcpp2 –c add.h,自动生成一些远程调用需要的文件
c、 接下来写一个服务端,创建文件 addserver.c
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
#include "soapH.h"
#include "add.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 \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, "Socket connection successful: master socket = %d\n", m);
for (;;)
{
soap_print_fault(&add_soap, stderr);
s = soap_accept(&add_soap);
if (s < 0)
{
exit(-1);
}
fprintf(stderr, "Socket connection successful: slave socket = %d\n", s);
soap_serve(&add_soap);
soap_end(&add_soap);
}
}
return 0;
}
int ns2__add(struct soap *add_soap, int num1, int num2, int *sum)
{
*sum = num1 + num2;
return 0;
}
d、 接着写一个客户端,文件名为 addclient.c
#include "soapStub.h"
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
#include "add.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("server is %s, num1 is %d, num2 is %d\n", server, num1, num2);
if (add_soap.error)
{
printf("soap
error:
%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;
}
e、 最后写一个测试代码,addtest.c
#include
#include
#include
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 num1 num2 \n", argv[0]);
exit(1);
}
strcpy(server,argv[1]);
num1 = atoi(argv[2]);
num2 = atoi(argv[3]);
result = add(server, num1, num2, ∑);
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
if (result != 0)
{
printf("soap error, errcode=%d\n", result);
}
else
{
printf("%d + %d = %d\n", num1, num2, sum);
}
return 0;
}
f、 到目前为止,自己的代码编写完毕,接下来编译服务端和客户端
注意:编译的时候要把 gsoap 包里的源代码文件 stdsoap2.c 和 stdsoap2.h 拷贝到
当前目录
Makefile 文件:
GSOAP_ROOT = gsoap 的解压路径/gsoap
WSNAME = add
CC = g++ -g -DWITH_NONAMESPACES
INCLUDE = -I$(GSOAP_ROOT)
SERVER_OBJS = soapC.o stdsoap2.o soapServer.o $(WSNAME)server.o
CLIENT_OBJS =
$(WSNAME)test.o
all: server
server: $(SERVER_OBJS)
$(CC) $(INCLUDE) -o $(WSNAME)server $(SERVER_OBJS)
client: $(CLIENT_OBJS)
$(CC) $(INCLUDE) -o $(WSNAME)test $(CLIENT_OBJS)
cl:
soapClient.o $(WSNAME)client.o
soapC.o
stdsoap2.o
rm
-f *.o *.xml *.a *.wsdl *.nsmap soapH.h $(WSNAME)Stub.*
$(WSNAME)server ns.xsd $(WSNAME)test
然后执行 make,即可生成 addserver 程序;执行 make client,生成 addtest 程序
g、 运行程序
执行 ./addserver 7777
终端打印出:Socket connection successful: master socket = 3
这是 sever 已经在前台运行起来了
运行客户端 ./addtest ip 地址:port num1 num2 返回加法的结果
第一个简单的例子到此结束
(2) 使用 wsdl2h
a、建立一个新的目录,命名为 weather
命令:mkdir weather
b、利用 gsoap 工具生成 webserice 协义代码,wsdl2h 从服务器下载头文件,
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
soapcpp2 相当于代码生成品,根据头文件生成相应的.c 文件和.nsmap 文件。
命令:wsdl2h -c -o weather.h http://www.ayandy.com/Service.asmx?WSDL
注:-c 生成.c 文件
命令:soapcpp2 -x -C -c weather.h
-x 不生成 xml 文件
-C 只生成客户端相关代码
c、拷贝 gsoap 目录下的 stdsoap2.h stdsoap2.c 两个文件到 weather 目录下。
d、编写客户端程序,也就是调用刚刚生成代码中接口函数。
#vim weather.c
#include
#include"soapH.h"
#include"ServiceSoap.nsmap"
#define CITY_NAME "北京"
int main(int argc, char *argv[])
{
struct soap soap;
int ret = 0;
int element = 0;
int i = 0;
soap_init(&soap);
soap_set_mode(&soap, SOAP_C_UTFSTRING);
soap.mode |= SOAP_C_UTFSTRING;
struct _ns1__getWeatherbyCityName cityname;
struct _ns1__getWeatherbyCityNameResponse response;
cityname.theCityName = CITY_NAME;
cityname.theDayFlag = 0;
if(soap_call___ns3__getWeatherbyCityName(&soap, NULL, NULL, &cityname,
&response) == SOAP_OK)
{
printf("get weather ok !\n");
element = response.getWeatherbyCityNameResult->__sizestring;
for(i = 0; i < element; i++)
{
printf("i(%d),
response.getWeatherbyCityNameResult->string[i]);
}
}
else
{
printf("soap_call___ns3__getWeatherbyCityName failed!\n");
}
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
string(%s)\n",
i,
return 0;
}
e、编写 makefile
#CROSS_COMPILER:=
CC:=$(CROSS_COMPILER)gcc
GCC:=$(CROSS_COMPILER)g++
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
all:
$(CC) -o weather weather.c soapC.c soapClient.c stdsoap2.c
clean:
rm -f weather
f、 编译、执行程序
命令:make
命令:./weather
执行成功则返回
g、常见问题:
get weather ok !
i(0) string((null))
i(1), string(北京)
i(2), string(晴)
i(3), string(7 ~ -4 ℃)
i(4), string(北风 4-5 级转微风)
i(5), string(今天)
i(6), string(http://www.ayandy.com/images/晴.gif)
i(7), string((null))
1 程 序 编 绎 通 过 , 但 是 运 行 ./weather 是 失 败 , 打 印
soap_call___ns3__getWeatherbyCityName failed
答:可能是你的 linux 主机的网络有问题,试试 ping 一下其它网络地址
http://www.ayandy.com 是否成功。
如何失败,则可能的原因有:网络没有连接到公网或者 dns 没有设置。
2 我运行./weather 后出现的打印为乱码,如下
get weather ok !
i(0), string((null))
i(1), string(?漪)
i(2), string(??
i(3), string(7 ~ -4 ??
i(4), string(?
i(5), string(隞予)
i(6), string(http://www.ayandy.com/images/??gif)
i(7), string((null))
答:这种情况是编码格式不正确,服务器返回的是 utf-8 的字符品, 所以
?4-5 蝥扯蓮敺桅?)
要求你的终端的设置的编码格式也为 utf-8.
(pietty 的设置方法,option->Encoding->Unicode utf-8)
4、 移植
关于 gsoap 程序的移植很简单只需要将编写完成的程序用交叉编译工具生成可执行文件
下载到目标板上即可。