zoukankan      html  css  js  c++  java
  • gSOAP 初体验

    安装

    由于本人使用的是 Mac OS 系统,故以 Mac OS 为例说明如何安装 gSOAP。

    1)下载 gSOAP

    可以在 https://sourceforge.net/projects/gsoap2 下载最新版本的 gSOAP。

    2)安装 flex, bison, openssl

    可以使用brew install进行安装:

    brew install flex bison openssl

    3)编译安装 gSOAP

    解压上面下载的 gSOAP,然后执行下面的命令:

    cd gsoap-2.8
    ./configure --with-openssl=/usr/local/opt/openssl
    make
    sudo make install

    安装完成,会出现以下的提示: 

    安装中如果出现 fatal error: 'openssl/bio.h' file not found 的错误,可以通过尝试重新安装 openssl 和使用最新的 gsoap-2.8 版本的方法来解决,具体解决办法也可以 google 一下。

    其他平台的安装教程可以参考官方文档:https://www.genivia.com/downloads.html

    gSOAP 工具

    gSOAP 提供了两个工具来方便开发人员使用 C/C++ 语言快速开发Web 服务应用,通过 gSOAP 提供的这两个工具,开发人员可以快速生成服务端与客户端代码框架,接下来开发人员只需要实现具体的接口函数即可。

    wsdl2h

    wsdl2h 工具根据 WSDL 文件生成 C/C++ .h 头文件。 
    WSDL(Web Service Description Language)即 Web 服务描述语言,它使用 XML 来对 Web 服务进行描述。 
    wsdl2h 的用法:

    wsdl2h -o 头文件名 WSDL文件名或URL

    例如:

    wsdl2h -o calc.h http://www.genivia.com/calc.wsdl

    wsdl2h 根据 URL 指定的 WSDL 生成calc.h头文件。calc.h对 Web 服务接口进行定义。

    wsdl2h 支持额外的参数:

    • -s 生成的头文件不使用 STL
    • -o 文件名,指定输出头文件的名称
    • -c 产生纯 C 代码,否则是 C++ 代码
    • -t 文件名,指定 type map 文件,默认是 typemap.dat

    soapcpp2

    soapcpp2 工具则从上面生成的头文件生成 SOAP 服务端和客户端框架代码。例如对于上面的cacl.h,使用 soapcpp2 命令:

    soapcpp2 -i -Iimport calc.h

    soapcpp2 也支持额外的参数:

    • -i 生成 C++ 包装类,客户端为 xxxProxy.h(.cpp),服务端为xxxService.h(.cpp)
    • -I 指定 import 的路径,比如需要引入stlvector.h文件来支持 STL vector 的序列化
    • -C 仅生成客户端代码
    • -S 仅生成服务端代码
    • -c 产生纯 C 代码,否则是 C++ 代码
    • -x 不要产生 XML 示例文件
    • -L 不要产生soapClientLib.csoapServerLib.c文件

    例子

    gSOAP 中包含了大量的例子以便让开发人员快速了解如何使用 gSOAP 开发 Web 服务。 
    我们以 gSOAP 的 samples 目录下的 calc++ 的代码为例,说明如何使用 gSOAP 来编写客户端和的服务端代码。

    calc++ 目录已经包含了 calc.h 头文件,这个头文件跟上面我们使用 wsdl2h 生成的 calc.h 头文件并不完全相同,为了实验的方便,我们使用 calc++ 目录的calc.h 头文件进行实验。

    calc.h头文件:

    //gsoap ns service method: add Sums two values
    int ns__add(double a, double b, double *result);
    
    //gsoap ns service method: sub Subtracts two values
    int ns__sub(double a, double b, double *result);
    
    //gsoap ns service method: mul Multiplies two values
    int ns__mul(double a, double b, double *result);
    
    //gsoap ns service method: div Divides two values
    int ns__div(double a, double b, double *result);
    
    //gsoap ns service method: pow Raises a to b
    int ns__pow(double a, double b, double *result);

    然后,我们使用 soapcpp2 工具来生成客户端和服务端的框架代码:

    soapcpp2 -i calc.h

    客户端代码

    calcclient.c++ 代码:

    #include "soapcalcProxy.h"
    #include "calc.nsmap"
    
    const char server[] = "http://127.0.0.1:8080";
    
    int main(int argc, char **argv)
    { if (argc < 4)
      { fprintf(stderr, "Usage: [add|sub|mul|div|pow] num num
    ");
        exit(0);
      }
      double a, b, result;
      a = strtod(argv[2], NULL);
      b = strtod(argv[3], NULL);
      calcProxy calc;
      calc.soap_endpoint = server;
      switch (*argv[1])
      { case 'a':
          calc.add(a, b, &result);
          break;
        case 's':
          calc.sub(a, b, &result);
          break;
        case 'm':
          calc.mul(a, b, &result);
          break;
        case 'd':
          calc.div(a, b, &result);
          break;
        case 'p':
          calc.pow(a, b, &result);
          break;
        default:
          fprintf(stderr, "Unknown command
    ");
          exit(0);
      }
      if (calc.error)
        calc.soap_stream_fault(std::cerr);
      else
        printf("result = %g
    ", result);
      return 0;
    }

    由于代码使用 STL,为了顺利编译通过,需要将 gSOAP 中的stdsoap2.cppstdsoap2.h文件拷贝到客户端和服务端代码所在的目录。 
    改写好客户端代码后,使用 g++ 进行编译:

    g++ -o calcclient++ calcclient.cpp soapC.cpp soapcalcProxy.cpp stdsoap2.cpp

    编译顺利通过。

    服务端代码

    calcserver.cpp代码如下,其中可以指定服务端的端口号:

    #include "soapcalcService.h"
    #include "calc.nsmap"
    
    int main(int argc, char **argv)
    { calcService calc;
      if (argc < 2)
        calc.serve();   /* serve as CGI application */
      else
      { int port = atoi(argv[1]);
        if (!port)
        { fprintf(stderr, "Usage: calcserver++ <port>
    ");
          exit(0);
        }
        /* run iterative server on port until fatal error */
        if (calc.run(port))
        { calc.soap_stream_fault(std::cerr);
          exit(-1);
        }
      }
      return 0;
    } 
    
    int calcService::add(double a, double b, double *result)
    { *result = a + b;
      return SOAP_OK;
    } 
    
    int calcService::sub(double a, double b, double *result)
    { *result = a - b;
      return SOAP_OK;
    } 
    
    int calcService::mul(double a, double b, double *result)
    { *result = a * b;
      return SOAP_OK;
    } 
    
    int calcService::div(double a, double b, double *result)
    { if (b)
        *result = a / b;
      else
      { char *s = (char*)soap_malloc(this, 1024);
        (SOAP_SNPRINTF(s, 1024, 100), "<error xmlns="http://tempuri.org/">Can't divide %f by %f</error>", a, b);
        return soap_senderfault("Division by zero", s);
      }
      return SOAP_OK;
    } 
    
    int calcService::pow(double a, double b, double *result)
    { *result = ::pow(a, b);
      if (soap_errno == EDOM)   /* soap_errno is like errno, but compatible with Win32 */
      { char *s = (char*)soap_malloc(this, 1024);
        (SOAP_SNPRINTF(s, 1024, 100), "<error xmlns="http://tempuri.org/">Can't take power of %f to %f</error>", a, b);
        return soap_senderfault("Power function domain error", s);
      }
      return SOAP_OK;
    }

    然后使用 g++ 来对服务端代码进行编译:

    g++ -o calcserver++ calcserver.cpp soapC.cpp soapcalcService.cpp stdsoap2.cpp

    编译同样顺利通过。

    测试

    运行上面编译好的calcservercalcclient可执行文件 
    来对 Web 服务进行测试,测试结果如下:

    转自:https://blog.csdn.net/lihao21/article/details/70168050

    参考资料

      1. https://www.cs.fsu.edu/~engelen/soapdoc2.html
      2. https://www.genivia.com/downloads.html
      3. https://www.genivia.com/dev.html
      4. http://blog.csdn.net/yangjun1115/article/details/29360389
      5. https://www.cs.fsu.edu/~engelen/calc.html
      6. http://commandos.blog.51cto.com/154976/130652
      7. http://www.cppblog.com/qiujian5628/archive/2008/10/11/54019.html
      8. http://blog.sina.com.cn/s/blog_5ee9235c0100de3g.html
  • 相关阅读:
    Android&读取Sdcard中的歌曲,ListView操作
    委托从数据库出来的类型分类处理
    分类信息网站
    Managed DirectX +C# 开发(入门篇)(二)
    ZedGraph控件的使用属性和例子代码
    【转】 c#ZedGraph 控件属性
    ZedGraph
    基于Visual C#的DirectX开发实例教程
    C#常用开源类库收集
    狄更斯《双城记》开场白
  • 原文地址:https://www.cnblogs.com/liushui-sky/p/9305068.html
Copyright © 2011-2022 走看看