VS2010使用c++、gSOAP创建的WebService 图文教程
环境
操作系统:Windows 7gsoap版本:2.8.32
C++编译器/开发环境:Visual Studio 2010
gSOAP是什么
gSOAP编译工具提供了一个SOAP/XML 关于C/C++ 语言的实现,从而让C/C++语言开发web服务或客户端程序的工作变得轻松了很多。绝大多数的C++web服务工具包提供一组API函数类库来处理特定的SOAP数据结构,这样就使得用户必须改变程序结构来适应相关的类库。与之相反,gSOAP利用编译器技术提供了一组透明化的SOAP API,并将与开发无关的SOAP实现细节相关的内容对用户隐藏起来。
下载gSOAP工具包
http://120.52.73.49/jaist.dl.sourceforge.net/project/gsoap2/gSOAP/gsoap_2.8.32.zip
gSOAP Toolkit
解压后把下面两个文件复制到“C:\Windows”目录下,或者添加环境变量,这 样就可以在任何位置执行命令:
soapcpp2.exe
wsdl2h.exe
一、编写一个头文件
文件名:itoa.h
//gsoap ns service name: itoa //gsoap ns service namespace: http://localhost/itoa.wsdl //gsoap ns service location: http://localhost //gsoap ns service executable: itoa.cgi //gsoap ns service encoding: encoded //gsoap ns schema namespace: urn:itoa int ns__itoa(int i, char **a);
二、生成wsdl和服务端代码
打开CMD命令行,切换目录到“itoa.h”文件所在目录,执行命令:
soapcpp2 -S -I C:\gSOAP\gsoap-2.8\gsoap\import itoa.h
执行完成后,会在文件夹下面生成以下文件:
经测试直接使用“soapcpp2 -S itoa.h”也是可以的;
三、创建项目
1、打开VS2010,文件》新建》项目
2、左侧模板中选择Visual c++,右侧选择 Win32 控制台应用程序,输入项目名称,选择保存位置,勾选“为解决方案创建目录”,确定
3、下一步
4、取消“预编译头”的选中状态,完成
四、配置编译
1、打开项目文件目录
2、将第二步生成的代码复制到项目目录下
3、添加文件到项目
4、选择要添加到项目的文件
这里没有列全,有几个文件(stdsoap2.h,stdsoap2.cpp)是需要从gSOAP的源码目录复制过来的
注意:并不是要把所有文件都添加到项目里!
5、替换“itoaServer.cpp”文件的内容,使用以下代码:
// itoaServer.cpp : 定义控制台应用程序的入口点。 // #include "soapH.h" #include <windows.h> #include "itoa.nsmap" #define BACKLOG (100) /* Max. request backlog */ DWORD WINAPI process_request(LPVOID*); int http_get(struct soap * soap); int main(int argc, char **argv) { struct soap soap; struct soap *tsoap; const char* fmt = "accepts socket %d connection from IP %d.%d.%d.%d\n"; soap_init(&soap); if ( argc < 2 ) { soap_serve(&soap); soap_destroy(&soap); soap_end(&soap); } else { soap.send_timeout = 60; soap.recv_timeout = 60; soap.accept_timeout = 3600; soap.max_keep_alive = 100; soap.fget = http_get; DWORD tid; HANDLE hThread; int port = atoi(argv[1]); // first command-line arg is port SOAP_SOCKET m, s; m = soap_bind(&soap, NULL, port, BACKLOG); if ( !soap_valid_socket(m) ) exit(1); printf("Socket connection successful %d\n", m); for ( ; ; ) { s = soap_accept(&soap); if ( !soap_valid_socket(s) ) { if ( soap.errnum ) { soap_print_fault(&soap, stderr); exit(1); } printf("server timed out\n"); break; } printf(fmt, s, (soap.ip>>24)&0xFF, (soap.ip>>16)&0xFF, (soap.ip>>8)&0xFF, soap.ip&0xFF); tsoap = soap_copy(&soap); // make a safe copy if ( !tsoap ) break; hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)process_request, tsoap, 0, &tid); if ( hThread == NULL ) { printf("can not create a thread for SOAP request processing.\n"); exit(-1); } } } soap_done(&soap); return 0; } DWORD WINAPI process_request(LPVOID* soap) { soap_serve((struct soap*)soap); soap_destroy((struct soap*)soap); soap_end((struct soap*)soap); soap_done((struct soap*)soap); free(soap); return 0; } // 服务消息的实现代码 int ns__itoa(struct soap *soap, int i, char **a) { *a = (char*)soap_malloc(soap, 11); sprintf(*a, "%d", i); return SOAP_OK; } int http_get(struct soap * soap) { FILE *fd = NULL; printf("call http_get.\n"); char *s = strchr(soap->path, '?'); if ( !s || strcmp(s, "?wsdl") ) return SOAP_GET_METHOD; fd = fopen("itoa.wsdl", "rb"); if ( !fd ) return 404; soap->http_content = "text/xml"; soap_response(soap, SOAP_FILE); for ( ; ; ) { size_t r = fread(soap->tmpbuf, 1, sizeof(soap->tmpbuf), fd); if ( !r ) break; if ( soap_send_raw(soap, soap->tmpbuf, r) ) break; } fclose(fd); soap_end_send(soap); return SOAP_OK; }6、编译生成,在项目名称上单击鼠标右键,选择重新生成
选择重新生成的好处是避免之前的生成错误影响本次生成的结果
7、生成成功后,从项目目录下将“itoa.wsdl”文件复制到输出目录
五、启动WebService并测试
1、打开CMD命令提示符
2、切换目录到生成输入目录
3、执行命令:itoaServer.exe 8087
后面的端口是可以自己定义的,你想用什么就输入什么,只要是未占用的,不是其它协议/服务常用的;
4、允许访问
5、打开浏览器,输入你的IP:端口号/itoa?wsdl 访问看看吧,正常的话应该显示“itoa.wsdl”文件的内容
2016-05-29更新
1、更新文件:itoa.h,添加了一个函数
//gsoap ns service name: itoa //gsoap ns service protocol: SOAP //gsoap ns service style: rpc //gsoap ns service namespace: http://localhost:8087/itoa?wsdl //gsoap ns service location: http://localhost:8087 //gsoap ns service encoding: encoded //gsoap ns schema namespace: urn:itoa int ns__itoa(int i, char **a); int ns__add(double a, double b, double& result);2、更新文件:itoaServer.cpp,加入代码:
//server端的实现函数与itoa.h中声明的函数相同,但是多了一个当前的soap连接的参数 int ns__add(struct soap *soap, double a, double b, double& result) { result = a + b; return 0; }3、ns与ns2的区别
目前只是发现如果头文件件中的函数名使用ns2开头的话(例如:ns2_itoa),那么生成的WSDL文件名就是“ns2.wsdl”,时间有限,还没有深入去研究;另外在官方用户手册中也会看到“//gsoap ns2 service”这样的,也没有尝试;
结束语
别人如果想访问你的WebService,必须能够拿到你的 wsdl 文件(本例中为:itoa.wsdl)才行,还有就是你的WebService运行的服务器IP及使用的端口。
这里只讲了如何用c++,gSOAP开发一个WebService供别人调用,以后再讲讲如何调用的吧。
相关源码下载:http://download.csdn.net/detail/testcs_dn/9528394
下一篇:VS2010使用c++、gSOAP调用WebService 图文教程
参考:
http://www.genivia.com/products.html
http://www.genivia.com/doc/soapdoc2.html
http://www.cppblog.com/qiujian5628/archive/2008/06/19/54019.html
http://www.cppblog.com/qiujian5628/archive/2008/09/16/61945.html