c++调用webservice接口的几种方法以及实例

3 篇文章 0 订阅

c++调用webservice接口的几种方法以及实例

前言

最近在做这方面的工作,过程中遇到一些问题,故在此整理并分享一下,让后来者少走一些弯路.废话不多说,直接上干货.
准备工具:sproxy.exe/wsdl.exe;gsoap.均存在我的网盘中(还有一些其他好东西),大家自行伸手.(提取码:cato )
这些工具都是积累下来的很实用的,大家取完了点个赞哈.

c++调用webservice的几种方法

目前,常用的调用方法有三种(个人知识有限,欢迎提点),本文中主要介绍第一和第三种方法:

  1. 使用sproxy.exe生成头文件,此种方法最简单,直接加载到项目中调用即可;
  2. 使用wsdl.exe生成头文件,加载到项目中调用,与第一点同理,但未尝试,有空再回来补充;
  3. 使用gsoap生成文件,把生成的相关文件均加载到项目中调用(此方法较第一点比较麻烦);

关于webservice的准备工作

首先你得有webservice地址,然后你才能够调用.
网上有很多公共的webservice接口,这里用其中一个"国内手机号码归属地查询WEB服务"来举个栗子.
一般的接口是这样的: http://www.webxml.com.cn/WebServices/MobileCodeWS.asmx

第一步,添加后缀

添加后缀 ?wsdl 得到如下网址:
http://www.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl
打开是这样,说明成功
在这里插入图片描述

第二步,保存文件

把网页上的这些文件另存为wsdl格式的文件,右键->另存为即可下载.
在这里插入图片描述
下载完成.

方法一:使用sproxy.exe生成头文件并使用

1.生成头文件

sproxy使用方法: sproxy.exe /wsdl /out:“生成头文件目录名称” “生成的wsdl文件的路径”
eg:我的文件放在F:\webservice.WSDL转换成C转换成C++代码中,使用cmd进入此文件夹,并输入命令:

F:\webservice.WSDL转换成C转换成C++代码> .\sproxy.exe /wsdl /out:"F:\webservice.WSDL转换成C转换成C++代码\MobileCodeWS.h" "F:\webservice.WSDL转换成C转换成C++代码\MobileCodeWS.wsdl"

执行完成后,会生成MobileCodeWS.h文件.
在这里插入图片描述

2.使用接口实例

观察一下生成的.h中要使用的接口:
在这里插入图片描述
有三个参数,最后一个参数是返回的结果.

1.首先添加头文件以及使用命名空间

    #include "MobileCodeWS.h"
    using namespace MobileCodeWS;

2.实例化

CMobileCodeWS *oMobileWS = new CMobileCodeWS;

3调用以及传参

int iRet = oMobileWS->getMobileCodeInfo((CComBSTR)"15481348245",(CComBSTR)"",&bsRet);

4转换

//BSTR转换方法使用_com_util::ConvertBSTRToString(bsRet)

注意:

  • CComBSTR头文件:<comdef.h>
  • 使用_com_util::ConvertBSTRToString需添加#pragma comment(lib, “comsuppw.lib”)

方法二:使用wsdl.exe

这个方法可能适合c#使用,c++未尝试,待更.
使用方法类似方法一,自行研究.

方法三:使用gsoap.exe生成文件

由于未知原因,在使用第一种方法时,第一步生成头文件就失败,无法解析wadl的内容,报error.因此本人在网上搜罗大牛的博客查询资料借鉴整理验证,集前人所得才可最终成功.此方法稍微复杂一点点点点,各位看官请耐心.

1.使用wsdl2生成头文件

注意:
如果说传输的内容中含有中文,则需要增加一个bat文件,把传输类型由std::string转为wchar_t*,由宽字符传输,则可以解决乱码问题.刚开始由于没有添加处理文件导致后续接收到的中文乱码,折腾了半天,希望大家少走弯路.
bat文件(用txt文本保存如下文件,再修改后缀为bat即可)中一句话:

xsd__string = | std::wstring | wchar_t*

在gsoap-2.8\gsoap\bin\win32目录下,首先使用wsdl2.exe生成头文件:

F:\gsoap-2.8\gsoap\bin\win32> .\wsdl2h.exe -o .\MobileCodeWS.h .\MobileCodeWS.wsdl
或者不生成wsdl文件,直接使用wsdl的网址也可以生成
F:\gsoap-2.8\gsoap\bin\win32> .\wsdl2h.exe -o .\MobileCodeWS.h http://www.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl
添加bat项:
F:\gsoap-2.8\gsoap\bin\win32> .\wsdl2h.exe -o .\MobileCodeWS.h .\MobileCodeWS.wsdl -t chinano1.bat

2.使用soapcpp2生成系列文件

 PS F:\gsoap-2.8\gsoap\bin\win32> .\soapcpp2.exe -C .\MobileCodeWS.h -I F:\gsoap-2.8\gsoap\import -x

soapcpp2常用选项
-C 仅生成客户端代码
-S 仅生成服务器端代码
-L 不要产生soapClientLib.c和soapServerLib.c文件
-c 产生纯C代码,否则是C++代码(与头文件有关)
-I 指定import路径
-x 不要产生XML示例文件
-i 生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)。

在这里插入图片描述
执行成功后会生成红框中的文件
在这里插入图片描述

3.使用实例

1.加载入项目中
把上图红框中的五个文件(除了soapClientLib.cpp),以及gsoap下的stdsoap2.h和stdsoap2.cpp两个文件添加到项目中.
在项目中添加这七个文件后,cpp文件需要修改属性:在项目中的cpp上右键属性,选择不使用预编译头.
在这里插入图片描述
2.调用流程
首先需要添加头文件:
#include “soapH.h”
#include “MobileCodeWSSoap.nsmap”

实例如下:

#include "stdafx.h"
#include <iostream>
#include "soapH.h"
#include "MobileCodeWSSoap.nsmap"
#include <fstream>
using namespace std;

int main () 
{  
	// SOAP的客户端
	struct soap m_oSoap;
	// WebService调用对象
	class _ns1__getMobileCodeInfo getMobileCodeObject;
	// WebService返回对象
	class _ns1__getMobileCodeInfoResponse getMobileCodeResponseObject;
	// SOAP初始化
	soap_init(&m_oSoap);
	// 调用函数的参数赋值
	char strName[24] = {0};
	sprintf(strName,"15742451354");
	wchar_t *wstrName = A2W(strName);
	getMobileCodeObject.mobileCode = wstrName;
/*如果生成头文件时没有修改类型,那么用如下方式赋值,接收的类型当然也是string:
std::string strName = "15742451354";
getMobileCodeObject.mobileCode = strName;
*/

	// 发送WebService请求,并获得返回结果
	int nResult = soap_call___ns1__getMobileCodeInfo(&m_oSoap,NULL,NULL,&getMobileCodeObject,getMobileCodeResponseObject);
	// 操作成功
	if(SOAP_OK == nResult)
	{
		// 输出返回结果
		wchar_t* strResult = getMobileCodeResponseObject.getMobileCodeInfoResult;
		wcout.imbue(locale("chs"));
		wcout<<"wcout:"<<strResult<<endl;
	}
	/// 关闭SOAP
	soap_destroy(&m_oSoap);
	soap_end(&m_oSoap);
	soap_done(&m_oSoap);

	system("pause");
}  
要建立一个标准C语言的Web服务器的404界面,需要以下步骤: 1. 创建一个404.html文件,包含你想要显示的404错误信息。 2. 在服务器的代码中,当客户端请求一个不存在的页面时,服务器应该返回一个HTTP响应码为404的响应头。可以使用以下代码: ```c char response_header[1024]; sprintf(response_header, "HTTP/1.1 404 Not Found\r\nContent-Length: %d\r\n\r\n", strlen(404html)); ``` 3. 将404.html文件的内容作为响应正文发送给客户端。可以使用以下代码: ```c char *html = read_file("404.html"); // 读取404.html文件内容 send(client_sock, response_header, strlen(response_header), 0); // 发送响应头 send(client_sock, html, strlen(html), 0); // 发送响应正文 ``` 注意,read_file函数需要自己实现,可以使用标准C库中的fopen和fread函数来实现。 4. 关闭客户端连接。 完整的示例代码如下: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> char *read_file(const char *filename) { FILE *file = fopen(filename, "r"); if (file == NULL) { return NULL; } fseek(file, 0, SEEK_END); long file_size = ftell(file); rewind(file); char *buffer = malloc(file_size + 1); fread(buffer, 1, file_size, file); buffer[file_size] = '\0'; fclose(file); return buffer; } void handle_client(int client_sock) { char buffer[1024]; recv(client_sock, buffer, sizeof(buffer), 0); char response_header[1024]; char *html; if (strstr(buffer, "GET / HTTP") != NULL) { html = read_file("index.html"); sprintf(response_header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n", strlen(html)); } else { html = read_file("404.html"); sprintf(response_header, "HTTP/1.1 404 Not Found\r\nContent-Length: %d\r\n\r\n", strlen(html)); } send(client_sock, response_header, strlen(response_header), 0); send(client_sock, html, strlen(html), 0); close(client_sock); free(html); } int main(int argc, char *argv[]) { int server_sock, client_sock; struct sockaddr_in server_addr, client_addr; int client_addr_len = sizeof(client_addr); server_sock = socket(AF_INET, SOCK_STREAM, 0); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(8080); bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)); listen(server_sock, 5); while (1) { client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &client_addr_len); handle_client(client_sock); } return 0; } ``` 在以上代码中,如果客户端请求的是根路径("/"),则返回index.html文件的内容,否则返回404.html文件的内容。你需要将404.html文件放在服务器的根目录下。
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值