简介

在C++中,一般使用gSOAP来实现客户端、服务端。然而,对小项目来说gSOAP太大了,也不太方便。我们完全可以自己实现SOAP协议,毕竟SOAP协议的本质就是:Http协议+XML。

文章C++中gSOAP的使用介绍了gSOAP的使用,本文就以它的服务端为例,实现一个SOAP客户端。这里需要使用下面两个库:

  • cpp-httplib:一个 C++11 单文件头文件跨平台、多线程“阻塞”的 HTTP/HTTPS 库,使用时只需在项目中包含httplib.h文件。
  • tinyxml2:tinyXML-2 是一个简单、小巧、高效的 C++ XML 解析器,可以轻松集成到其他程序中,用来代替tinyxml,使用时只需在项目中包含 tinyxml2.cpp 和 tinyxml2.h 文件。

库的使用方法可以参考以下文章或github:

实现客户端

一个SAOP客户端的主要工作流程有3步:构建请求数据的xml、执行Http协议的POST方法、解析响应数据的xml。

准备xml文件

准备请求数据、响应数据的xml文件,请求数据的xml文件在项目中作为模板使用,响应数据的xml文件仅用于开发参考不是项目必须的文件。

请求数据的xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns="http://tempuri.org/ns.xsd">
<SOAP-ENV:Body>
<ns:add>
<a>0</a>
<b>0</b>
</ns:add>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

响应数据的xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns="http://tempuri.org/ns.xsd">
<SOAP-ENV:Body>
<ns:addResponse>
<result>0.0</result>
</ns:addResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

引入库文件

头文件引用如下:

#include "httplib.h"
#include"tinyxml2.h"
#include <iostream>
#include <string>
using namespace std;
using namespace tinyxml2;

项目文件如下:

构建请求数据的xml

使用tinyxml的文档对象加载xml文件,设置文档对象的节点内容,然后返回xml内容,代码如下:

string CreateReqXml_Add(int a, int b)
{
tinyxml2::XMLDocument doc;
doc.LoadFile("addReqXML.xml");
tinyxml2::XMLElement* pNode = doc.FirstChildElement("SOAP-ENV:Envelope")
->FirstChildElement("SOAP-ENV:Body")
->FirstChildElement("ns:add"); pNode->FirstChildElement("a")->SetText(a);
pNode->FirstChildElement("b")->SetText(b);
XMLPrinter printer;
doc.Print(&printer);
return printer.CStr();
}

执行Http协议的POST方法

构建一个httplib的客户端对象,直接执行POST方法,代码如下:

int a = 12;
int b = 13;
string strdata = CreateReqXml_Add(a, b);
httplib::Client cli("http://localhost:8080");
auto res = cli.Post("/", strdata, "text/xml; charset=utf-8");

注:httplib内部对socket使用了线程锁,可以在多线程中使用一个客户端对象执行Http方法。

解析响应数据的xml

根据Http方法返回的Result对象判断方法是否成功,Result对象有operator bool() const { return res_ != nullptr; }重载可以直接判断,代码如下:

if (res)
{
cout << res->status << endl;
cout << res->get_header_value("Content-Type") << endl;
cout << res->body << endl;
cout << "Result:" << ParseResXml_Add(res->body) << std::endl;
}
else
{
cout << "error code: " << res.error() << std::endl;
}

解析响应数据xml的方法如下:

string ParseResXml_Add(string xmlStr)
{
tinyxml2::XMLDocument doc;
doc.Parse(xmlStr.c_str(),xmlStr.length());
string result= doc.FirstChildElement("SOAP-ENV:Envelope")
->FirstChildElement("SOAP-ENV:Body")
->FirstChildElement("ns:addResponse")
->FirstChildElement("result")->GetText();
return result;
}

测试客户端

先启动服务端,在启动客户端的调试,结果如下:

200
text/xml; charset=utf-8
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="http://tempuri.org/ns.xsd"><SOAP-ENV:Body><ns:addResponse><result>25</result></ns:addResponse></SOAP-ENV:Body></SOAP-ENV:Envelope> Result:25

附件

C++实现一个SOAP客户端的更多相关文章

  1. 用VisualC++建立SOAP客户端应用(一)

    用VisualC++建立SOAP客户端应用(一) SoapSerializer对象用来构建一个向Web服务发送的SOAP消息.在与服务器连接前,SoapSerializer对象必须与SoapConne ...

  2. 我的第一个REST客户端程序!

    Delphi:XE8 看了好几天的资料了,也没有弄出来一个REST程序,尝试了XE8中带的例子,也都没有搞懂.我在网上不断搜索,看是否能够找到适合自己的文章,希望能够做出来一个REST的小例子,万幸, ...

  3. zabbix学习-如何部署一个agent客户端

    1. 部署一个agent客户端很简单,比如监控服务器本身 yum install zabbix-agent -y 2.配置文件位置: vim /etc/zabbix/zabbix-agendt.con ...

  4. 使用c++实现一个FTP客户端(一)

    之前使用c++实现了一个FTP客户端,在这里做一些记录. 一.需要注意的几点 ①FTP是一种文件传输协议,基于TCP,所以客户端与服务器建立的连接是可靠.安全的,并且要经过三次握手的过程. ②FTP传 ...

  5. 学习T-io框架,从写一个Redis客户端开始

    前言   了解T-io框架有些日子了,并且还将它应用于实战,例如 tio-websocket-server,tio-http-server等.但是由于上述两个server已经封装好,直接应用就可以.所 ...

  6. UWP使用AppService向另一个UWP客户端应用程序提供服务

    原文:UWP使用AppService向另一个UWP客户端应用程序提供服务 在上篇里,我使用的是寄宿在WPF上的WCF进行两个程序间的通信,在解决问题的同时,我的同事也在思考能否使用UWP来做这件事.于 ...

  7. 两个ESP8266一个作为服务器一个作为客户端实现互相通讯

    两个ESP8266一个作为服务器一个作为客户端实现互相通讯

  8. 如何测试手机上的SOAP客户端

    周四晚上,服务端和客户端的两个同事因为soap接口的问题争论了起来.服务端的同事认为客户端的同事发给服务端的soap消息的xml结构有问题,少了几个xml节点,导致服务器端解析出错.而客户端的同事认为 ...

  9. 使用c++实现一个FTP客户端(三)

    接上篇:http://www.cnblogs.com/jzincnblogs/p/5217688.html,这篇主要记录编程过程中需要注意的地方以及遇到的一些问题及解决方法. 一.gethostbyn ...

随机推荐

  1. Django边学边记—模型查询

    查询集 两大特性 惰性执行:创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代.序列化.与if合用 缓存:查询集的结果被存下来之后,再次查询时会使用之前缓存的数据 返回列 ...

  2. Dapr + .NET Core实战(五)Actor

    什么是Actor模式 Actors 为最低级别的"计算单元" 以上解释来自官方文档,看起来"晦涩难懂".大白话就是说Actors模式是一段需要单线程执行的代码块 ...

  3. centos7.5 SVN 搭建

    第一步:通过yum命令安装svnserve,命令如下: >yum -y install subversion 此命令会全自动安装svn服务器相关服务和依赖,安装完成会自动停止命令运行 若需查看s ...

  4. 定要过python二级 选择题第四套

    1. 2. 3. 4. 5. 6. python用于人工智能 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.

  5. 鸿蒙内核源码分析(信号生产篇) | 信号安装和发送过程是怎样的? | 百篇博客分析OpenHarmony源码 | v48.03

    百篇博客系列篇.本篇为: v48.xx 鸿蒙内核源码分析(信号生产篇) | 年过半百,依然活力十足 | 51.c.h .o 进程管理相关篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁在管 ...

  6. CF848E-Days of Floral Colours【dp,分治NTT】

    正题 题目链接:https://www.luogu.com.cn/problem/CF848E 题目大意 \(2n\)个花排成一个圆环,\(n\)种颜色每种两个,要求两个相同颜色之间最小距离为\(1, ...

  7. JQuery EasyUI 结合ztrIee的后台页面开发

    JQuery EasyUI 结合 zTree树形结构制作web页面.easyui用起来比较简单,很好的封装了jquery的部分功能,使用起来更加方便,但是从1.2.3版本以后,商业用途是需要付费的, ...

  8. 【C++ Primer Plus】编程练习答案——第6章

    1 void ch6_1() { 2 using namespace std; 3 char ch; 4 while ((ch = cin.get()) != '@') { 5 if (isdigit ...

  9. A Three-Stage Self-Training Framework for Semi-Supervised Semantic Segmentation

    论文阅读笔记: A Three-Stage Self-Training Framework for Semi-Supervised Semantic Segmentation 基本信息 \1.标题:A ...

  10. [FFMpeg] 非标准分辨率视频Dump YUV注意事项

    背景 做视频编解码相关开发的过程中我们经常会遇到要把视频原始YUV数据保存下来查看的情况. 使用FFMpeg对视频解码之后原始图片数据都是保存在AVFrame这一结构中,很多时候我们都按照图像的长宽来 ...