一、gSoap简介
1.1、soap协议
介绍gsoap需要先了解soap协议,soap名叫简单对象访问协议,是交换数据的一种协议规范。其特点是轻量、简单、基于XML,它被设计成在WEB上交换结构化和固化的信息。
SOAP采用了已经广泛使用的两个协议:HTTP和XML(遵循标记语言的下一个子集)。HTTP用于实现SOAP的RPC风格的传输,而XML是它的编码模式。采用几行代码和XML解析器,HTTP服务器(IIS或者Apache)成为SOAP的ORBS。SOAP通讯协议采用HTTP来发送XML格式的信息。HTTP与RPC的协议很相似,他简单配置广泛,并且对防火墙比其他协议更容易发挥作用。HTTP请求一般由Web服务器软件(IIS和Apache)来处理,但越来越多的应用服务器产品正在支持HTTP。XML作为一个更好的网络数据表达方式(NDR)。SOAP把XML的使用代码化为请求和响应参数编码模式,并用HTTP作传输。具体的讲,一个SOAP方法可以简单地看作遵循SOAP编码规则的HTTP请求和响应,一个SOAP终端可以看作一个基于HTTP的URL,它用来识别方法调用的目标。像CORBA/IIOP一样,SOAP不需要具体的对象绑定到一个给定的终端,而是由具体的实现程序来决定怎样把对象终端标识符映像到服务器端对象。
1.2、gSoap工具
gSoap就是一个工具,提供一个SOAP/XML关于C/C++语言的实现,从而让C/C++语言开发web服务或者客户端程序的工作变得轻松了很多。绝大多数的C++ web服务工具包提供一组API函数类库来处理特定的SOAP数据结构,这样就使得用户必须改变程序结构来适应相关类库。与之相反,gSoap利用编译器技术提供了一组透明化的SOAP API,并将与开发无关的SOAP实现细节相关的内容对用户隐藏起来。
二、gSoap环境准备
首先电脑上要具备相关的环境,这里我在ubuntu14.04下进行尝试,尝试之前要安装很多东西以免发生编译错误:
sudo apt-get install build-essential flex bison openssl libssl-dev libssl0.9.8 checkinstall libgtk2.0-dev libglib2.0-dev
https://sourceforge.net/projects/gsoap2/files/gSOAP
可以看到还是需要安装很多很多的东西的,不然编译会报各种错。下载的是最新版本的gSOAP 2.8 ,该软件是基于GPL V2进行开源的。使用时候注意相关规范。将下载下来的代码进行解压。按照下面过程进行配置和编译。
./configure
make
make install
中间在make的时候可能还有遇到有其他问题,这里就可以直接百度看看是不是环境中却什么包。安装上后如果编译还是有问题,可以尝试 make clean && make distclean 两条命令执行后再进行配置和编译操作。
以下是一个Makefile文件,需要将其单独放在一个空文件夹中,进行测试:
声明:这个Makefile 来自 chinaunix大神 “chenshko” 转载文章,原文章出现在百度贴吧中,现在网页已经打不开了,很抱歉这里追溯不到原作者了:
server := myServer
client := myClient
test := soapTester
#your gsoap install directory
GSOAP_DIR=/root/Desktop/gsoap-2.8
#compiler
CORSS_COMPILER =
G++ :=$(CORSS_COMPILER)g++
#flags
LIBS:= -lpthread -lm
INCLS := -I ./ -I $(GSOAP_DIR)/gsoap
CFLAGS := -O2 -Wall -Wno-deprecated-declarations
COM_SOURCES := soapC.cpp $(GSOAP_DIR)/gsoap/stdsoap2.cpp
COM_OBJS := $(COM_SOURCES:.cpp=.o)
OBJ_SOURCES := $(server).cpp soapServer.cpp $(client).cpp soapClient.cpp $(test).cpp
OBJS := $(OBJ_SOURCES:.cpp=.o) $(COM_OBJS)
#MAKE
.PHONY: all wsdl gsoap server client test
all: test
server: wsdl gsoap makeServer
client: wsdl gsoap makeClient
test: wsdl gsoap makeTest
#files
WSDL_FILES := temp.h
GSOAP_FILES := soapClient.cpp soapServer.cpp soapC.cpp soapH.h soapStub.h
WSDL_SOURCE := $(wildcard *.wsdl)
ifeq ( , $(WSDL_SOURCE))
WSDL_SOURCE := $(GSOAP_DIR)/gsoap/WS/WS-Discovery.wsdl
endif
TYPEMAP = $(wildcard *typemap.dat)
ifeq ( , $(TYPEMAP))
TYPEMAP = $(GSOAP_DIR)/gsoap/typemap.dat
endif
wsdl:
ifneq ($(WSDL_FILES), $(wildcard $(WSDL_FILES)))
$(GSOAP_DIR)/gsoap/wsdl2h -P -t $(TYPEMAP) $(WSDL_SOURCE) -o temp.h
endif
gsoap:
ifneq ($(GSOAP_FILES), $(wildcard $(GSOAP_FILES)))
$(GSOAP_DIR)/gsoap/src/soapcpp2 -x -L -T -I $(GSOAP_DIR)/gsoap/import:$(GSOAP_DIR)/gsoap $(WSDL_FILES)
endif
makeServer:$(server).o soapServer.o $(COM_OBJS)
$(G++) $(INCLS) $(CFLAGS) -o $(server) $^ $(LIBS)
makeClient:$(client).o soapClient.o $(COM_OBJS)
$(G++) $(INCLS) $(CFLAGS) -o $(client) $^ $(LIBS)
makeTest:$(test).o soapServer.o soapClient.o $(COM_OBJS)
$(G++) $(INCLS) $(CFLAGS) -o $(test) $^ $(LIBS)
$(OBJS) :%.o:%.cpp
$(G++) $(INCLS) $(CFLAGS) -o $@ -c $^
#clean
clean:
@rm -rfv *.o *~ *Proxy.h *Object.h $(server) $(client) $(test)
deepClean:
@rm -rfv *.o *~ *Proxy.h *Object.h $(server) $(client) $(test) *.nsmap $(GSOAP_FILES) $(WSDL_FILES) soapTester.cpp
这里需要将 GSOAP_DIR 后面的目录修改为自己的解压的gSoap2.8的目录。然后make下就可以看到 soapTester生成成功了。代表这个环境已经配置成功了。注意:以上代码直接复制会让Tab变成空格导致make的时候报规则错误,请将空格替换为tab即可。
三、一个小尝试(gsoap qq状态查询程序(并非实时准确))
再次新建一个文件夹,这里我文件夹建立在了 gsoap-2.8/selfqqtest 中。先将之前编译生成的两个工具(wsdl2h、soapcpp2)拷贝到该目录。
生成相关文件
wsdl2h -c -o qq.h [http://www.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl](http://www.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl) //-c 是只生产 C 语言的程序
soapcpp2 -C qq.h //这里只开发Client端程序,所以仅加了一个-C
这时候所在目录下会生成很多文件了。我这里例举下我生产的文件:
qqOnlineWebServiceSoap.qqCheckOnline.req.xml
qqOnlineWebServiceSoap.qqCheckOnline.res.xml
qq.h
qqOnlineWebServiceSoap.nsmap
soapC.c
soapClientLib.c
soapClient.c
soapH.h
soapStub.h
这里我们再处理下客户端程序:qqOnline.c
include “soapH.h”
include “qqOnlineWebServiceSoap.nsmap”
int main(int argc, char **argv)
{
if (argc != 2){
printf(“Usage: %s qq_code\n”, argv[0]);
exit(-1);
}
struct soap soap;
soap_init(&soap);
struct _ns1__qqCheckOnline request;
struct _ns1__qqCheckOnlineResponse response;
request.qqCode = argv[1];
if (soap_call___ns1__qqCheckOnline(&soap, NULL, NULL, &request, &response) == SOAP_OK){
char *state = NULL;
if (strcmp(response.qqCheckOnlineResult, “Y”) == 0)
state = “在线”;
if (strcmp(response.qqCheckOnlineResult, “N”) == 0)
state = “不在线”;
printf(“你的QQ:%s 状态是:%s\n”, argv[1], state);
} else {
soap_print_fault(&soap, stderr);
}
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
return 0;
}
然后再使用gcc编译下就可以了。
gcc -O2 -o qq qqOnline.c soapC.c soapClient.c ../gsoap/stdsoap2.c -I../gsoap/ -L../gsoap/
这里就会生产qq 文件了。这时候就可以进行测试了。
./qq 123456
然后发现输出说竟然在线。后面发现只要位数对基本都是在线,因为不是对接的腾讯的接口,查询出来的结果有问题很正常。
四、参考文献
- http://www.fx114.net/qa-227-66112.aspx 《gSOAP开发实例(一)qq在线客户端》
- http://blog.csdn.net/wind_breez/article/details/6097632 《使用gSOAP实现一个简单的QQ在线状态查询程序》 作者:wind_breez
- http://blog.chinaunix.net/uid-21768364-id-4648583.html 《linux下gsoap编程》作者:chenshko
真诚感谢以上文献的作者~