• vc++2008 采用GSoap访问 WebService


    前一阶段写gSOAP 的文章没保存好,后来想写的,越学越没有写的勇气了,感觉自己很菜,但是现在感觉还是写点就算给入门者一点提示吧。另外虽说这篇文章是自己写的,但是却感觉是东拼西凑的,有很多别人的东西了。
       看了我转载的关于soap 的文章,大家想必对soap有所了解了吧,那么gSOAP是什么那?
    gSOAP 是一个开源的项目,用它可以方便的使用c/c++地进行SOAP客户端和服务器端编程,而不必了解xml和SOAP协议的细节。这样使用者就可以专注于自 己的web service 客户端或服务器端的编写,而不用纠缠与其它细节。我第一次接触这些东西,我对SOAP的理解是这样的:以http协议为基本的通信协议,以xml文件形式 请求远程服务,再以xml文件的形式返回执行结果,我理解的就这么简单了,有啥不妥处,还请指教阿。
    实践一下才有理性认识,下面是我自己在windows下,具体说来就是用vc 6.0下编写的一个很简单的客户端程序调用远程的服务,来发送电子邮件,感觉很爽吧。
    首先我们到 http://sourceforge.net/project/showfiles.php?group_id=52781 下载gSOAP下载工具集吧,不同的系统下用的gSOAP是不一样的,根据需要下载了windows下的和linux下的。
    gSOAP工具集不需要安装,直接解压就可以了。在/bin目录下我们可以看到两个可执行文件:
    soapcpp2.exe: gSOAP编译器,编译头文件生成服务器和客户端都需要的 c/c++文件。 
    wsdl2h.exe: 编译wsdl文件生成c/c++头文件。
    工具就算准备好了。
    其次,我们到 http://www.abysal.com/soap/AbysalEmail.wsdl 下载
    wsdl文件,假设保存文件名为:AbysalEmail.wsdl。所谓的wsdl文件翻译成中
    文就是网络服务描述文件了。我们用wsdl2h.exe工具来根据wsdl文件生成
    c/c++头文件,可以用-c选项是生成纯c的头文件,另外用-s选项是说明我们在
    程序中不使用stl,注意了默认我们是适用stl的。
    用如下命令:
    wsdl2h  -o AbysalEmail.h AbysalEmail.wsdl
    既可以生成我们需要的AbysalEmail.h头文件了。这里文件名可以随便起了。
    将下载的gsoap的import里的stlvector.h中文件拷贝到当前的文件夹下,因为默认是使用stl的,所以需要它。
    然后执行soapcpp2 命令来生成存根程序,用如下命令:
    soapcpp2  -C AbysalEmail.h
    -C  选项是只生成客户端的,默认是生成客户端和服务器端的,如果你在程序中使用了vector还要加上 –limport选项。
    即可以生存客户端存根程序和框架了。
    soapClient.cpp:编译客户端的需要的存根例程。
    soapC.cpp,soapH.h:用来序列化和反序列化c/c++不同数据类型。
    soapServer.cpp: 编译服务器端的需要的存根例程。
    soapXXXProxy.h: 生成的代理类的头文件,使用代理类时需要此文件。
    本程序为soapSendEmailBindingProxy.h。

    第三步,就是在vc中建个工程,设置如下:
    在vc6中建立工程,其源文件为:sendMailClient.cpp soapC.cpp 
                                        soapClient.cpp   stdsoap2.cpp
    头文件为:      AbysalEmail.h soapH.h soapStub.h stdsoap2.h      
    其他依赖文件为:basetsd.h  sendemailbinding.nsmp
    stdsoap2.cpp stdsoap2.h是下载的gSOAP中包含的。
    另外在所需要的库中把wsock32.lib加上,gSOAP也是采用socket方式连接的。(添加方法:项目->属性->连接器->输入->附加依赖项 添加wsock32.lib)
    其中sendMailClient.cpp为我写的客户端程序,程序如下:

    #include "soapH.h"                          // 得到存根程序
    #include "SendEmailBinding.nsmap"            //得到名称空间映射表
    #include <iostream>
    #include  <string>
    #include "soapSendEmailBindingProxy.h"

    using namespace std;

    int main(int argc, char **argv) 
    {
            struct soap email_soap;
            int result = -1;
       SendEmailBinding  EmailBind;              //生成代理类对象
        _ns1__SendEmail  sendEmail;              //web服务发送电子邮件对象
       _ns1__SendEmailResponse  Email_Response;  //web 服务返回发送结果对象
       string from = "mseaspring";
       string to   = "David";
       string sub = "Hello test!";
       sendEmail.From = &from;
       sendEmail.FromAddress = " mseaspring@hotmail.com ";
       sendEmail.MsgBody = "I want to test a web service!";
       sendEmail.To = &to;
       sendEmail.ToAddress = " mseaspring@gmail.com ";
       sendEmail.Subject = ⊂

            result = EmailBind.__ns1__SendEmail(&sendEmail,  &Email_Response);
            if (result != 0)
            {
                    printf("soap error ,errcode = %d ", result);
            }
            else
            {
                cout<<"The result is :"<<Email_Response.ReturnCode<<endl;
                    cout<<"恭喜你,邮件发送成功!"<<endl;
            }
            return 0;
    }我程序中是采用代理类的方式编写的程序,不用代理类的代码如下:
    #include "soapH.h"                          //  得到存根程序
    #include "SendEmailBinding.nsmap"            // 得到名称空间映射表
    #include <iostream>
    #include  <string>
    using namespace std;

    int main(int argc, char **argv) 
    {
            struct soap email_soap;
            //初始化gSoap运行时环境变量,只需初始化一次
            soap_init(&email_soap);
            int result = -1;
            //远程web服务的endpoint URL .不要带WSDL
       const char* server="http://www.abysal.com/soap/soapmail.wdtp";
       string from = "mseaspring";
       string to   = "David";
       string sub = "Hello test!";
       sendEmail.From = &from;
       sendEmail.FromAddress = " mseaspring@hotmail.com ";
       sendEmail.MsgBody = "I want to test a web service!";
       sendEmail.To = &to;
       sendEmail.ToAddress = " mseaspring@gmail.com ";
       sendEmail.Subject = ⊂
        //调用根据远程服务产生函数的接口
    result = soap_call___ns1__SendEmail(&email_soap, server, "", &sendEmail,  &Email_Response);
            if(email_soap.error)
            {
                    //在stderr流中打印soap的错误信息
                    soap_print_fault(&email_soap,stderr);
                    result = email_soap.error;
            }
        soap_destroy(&email_soap);// 删除反序列化类的实例,仅用于c++
            soap_end(&email_soap);    // 清空已经并行化的数据
            soap_done(&email_soap);   // 与gSOAP 环境相分离,关闭连接
            if (result != 0)
            {
                    printf("soap error ,errcode = %d ", result);
            }
            else
            {
                cout<<"The result is :"<<Email_Response.ReturnCode<<endl;
                    cout<<"恭喜你,邮件发送成功!"<<endl;
            }
            return 0;
    }
    你可能会问我怎么知道远程服务的接口阿? 到soapStub.h中去找就可以了,至于代理类的使用,到代理类头文件中一看便知。
    好了,终于要写完了,当然我们不仅可以编写客户端也可以编写服务器端程序,至于服务器端,有兴趣的可以自己看看gSOAP里面的文档,也很简单的,不过也要花点时间学习的了,呵呵。
    如果对于上面程序,有谁没调试成功联系我,邮箱都写在程序里那。呵呵。

    soap_set_mode(&soap, SOAP_C_UTFSTRING); 

    采用UTF-8的形式编码发送和接收到的文字,可防止中文乱码。

  • 相关阅读:
    20172327 2018-2019-1 《程序设计与数据结构》第二周学习总结
    20172327 2018-2019-1 《程序设计与数据结构》第一周学习总结
    20172327 2018-2019-1 《第一行代码Android》第二章学习总结
    20172327 2018-2019-1 《第一行代码Android》第一章学习总结
    学号 2017-2018-2《程序设计与数据结构》课程总结
    20172327 2017-2018-2 《程序设计与数据结构》实验5报告
    Django框架(五)-- 视图层:HttpRequest、HTTPResponse、JsonResponse、CBV和FBV、文件上传
    Django框架(四)-- 路由控制:有名/无名分组、反向解析、路由分发、名称空间、伪静态、APPEND_SLASH、不同版本的Django区别、Django虚拟环境搭建
    Django框架(三)-- orm增删改查、Django生命周期
    Django框架(二)-- 基本配置:app注册、模板配置、静态文件配置、数据库连接配置post和get
  • 原文地址:https://www.cnblogs.com/xumaojun/p/8543199.html
Copyright © 2020-2023  润新知