Win10搭建WebService

前言

因为项目需要使用 WebService,本人也是第一次使用 WebService,属于完全没有经验。多亏万能的以太网。下面对第一次搭建 WebService 服务端写一个简单的总结。

开发环境搭建

系统环境

Win10 + gSoap 2.8.119
服务端程序目前使用 VS2019。

gSoap 安装

下载 gSoap

gSoap 只需要直接从网络下载就可以,不需要本地编译,就是下载有些慢。下载地址为:
https://sourceforge.net/projects/gsoap2/files/
我选择了最新版本,也就是 gSoap 2.8.119。

解压

下载后是一个 zip 文件,直接解压即可。我解压在 d:/gsoap 目录下。我们需要使用的可执行文件有
在这里插入图片描述

添加路径

将 D:\gsoap-2.8\gsoap\bin\win64 添加到系统环境变量中。如下图。
在这里插入图片描述
这样,gSoap 就安装好了。

gSoap 重要工具介绍

wsdl2h

该工具的主要功能是,通过 wsdl 文件生成 C/C++ .h头文件。

socapcpp2

此工具用来从头文件,生成SOAP服务器及客户端代码,还包括WSDL、测试用XML数据。

第一个 Web Service 服务器端

刚开始看网络资料的时候,需要建立一个 wsdl 文件,还从网络上下载,看到自己完全不知所云。还好找到一个资料自己建立完整的服务端。

创建服务端文件夹

我在 d:\gsoap-2.8\gsoap。如下图。创建了一个 gServer 目录。
在这里插入图片描述
这个目录在任意位置。

建立提供服务的头文件

我们用一个最常见的计算器功能来实现 Web Service 服务端,提供一些基本的运算。

#ifndef __GSERVICE_H__
#define __GSERVICE_H__
//gsoap ns service name: gservice
//gsoap ns service style: rpc 

int ns__add(double num1, double num2, double& result );
int ns__sub(double num1, double num2, double& result );
int ns__mult(double num1, double num2, double& result);
int ns__divid(double num1, double num2, double& result);

#endif

当前文件夹如下。
在这里插入图片描述

生成 wsdl 文件

使用下面的命令行,

soapcpp2.exe -S gservice.h

来生成 wsdl 等文件。完整的记录过程如下。

D:\gsoap-2.8\gsoap\gServer>soapcpp2.exe -S gservice.h

**  The gSOAP code generator for C and C++, soapcpp2 release 2.8.119
**  Copyright (C) 2000-2021, Robert van Engelen, Genivia Inc.
**  All Rights Reserved. This product is provided "as is", without any warranty.
**  The soapcpp2 tool and its generated software are released under the GPL.
**  ----------------------------------------------------------------------------
**  A commercial use license is available from Genivia Inc., contact@genivia.com
**  ----------------------------------------------------------------------------

Saving soapStub.h annotated copy of the source interface header file
Saving soapH.h serialization functions to #include in projects
Using ns service name: gservice
Using ns service style: rpc
Using ns service encoding: literal
Using ns schema namespace: http://tempuri.org/ns.xsd
Saving gservice.wsdl Web Service description
Saving gservice.add.req.xml sample SOAP/XML request
Saving gservice.add.res.xml sample SOAP/XML response
Saving gservice.sub.req.xml sample SOAP/XML request
Saving gservice.sub.res.xml sample SOAP/XML response
Saving gservice.mult.req.xml sample SOAP/XML request
Saving gservice.mult.res.xml sample SOAP/XML response
Saving gservice.divid.req.xml sample SOAP/XML request
Saving gservice.divid.res.xml sample SOAP/XML response
Saving gservice.nsmap namespace mapping table
Saving ns.xsd XML schema
Saving soapServer.cpp server request dispatcher
Saving soapServerLib.cpp server request dispatcher with serializers (use only for libs)
Saving soapC.cpp serialization functions

Compilation successful

这样,我们就生成了所需要的 gservice.wsdl,gservice.nsmap。如下图所示。
在这里插入图片描述

使用 vs2019 建立服务端工程

我使用了 vs2019,在 D:\gsoap-2.8\gsoap\gServer 目录下生成了一个控制台应用。
在这里插入图片描述
在这里插入图片描述
然后点击创建。生成的空白项目如下图。
在这里插入图片描述
在这里插入图片描述

拷贝必须的文件

将 stdsoap2.h,stdsoap2.c,stdsoap2.cpp 拷贝到 gServer 目录下,这三个文件是 gSoap 提供的,在 D:\gsoap-2.8\gsoap 目录下。

加入必须的头文件

并将stdsoap2.h、soapStub.h、soapH.h、gservice.nsmap和stdsoap2.cpp、soapC.cpp、soapServer.cpp文件导入到gServer中,项目目录结构如下。
在这里插入图片描述

修改 gServer.cpp

增加 soap 相关代码

在 main() 中增加 soap 服务,端口等。

// gServer.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include "stdio.h"
#include "../soapH.h"
#include "../gservice.nsmap"

int main(int argc, char** argv)
{
	int nPort = 8080;
	struct soap fun_soap;
	soap_init(&fun_soap);
	int nMaster = (int)soap_bind(&fun_soap, NULL, nPort, 100);
	if (nMaster < 0)
	{
		soap_print_fault(&fun_soap, stderr);
		exit(-1);
	}

	fprintf(stderr, "Socket connection successful : master socket = %d\n", nMaster);

	while (true)
	{
		int nSlave = (int)soap_accept(&fun_soap);
		if (nSlave < 0)
		{
			soap_print_fault(&fun_soap, stderr);
			exit(-1);
		}

		fprintf(stderr, "Socket connection successful : slave socket = %d\n", nSlave);

		soap_serve(&fun_soap);
		soap_end(&fun_soap);
	}

	return 0;
}

接口相关代码

将 gservice.h 定义的函数实现。

/*加法的具体实现*/
int ns__add(struct soap* soap, double num1, double num2, double& result)
{
	result = num1 + num2;
	printf("[add] num1 = %lf, num2 = %lf, result = %lf\n", num1, num2, result);
	return SOAP_OK;
}

/*减法的具体实现*/
int ns__sub(struct soap* soap, double num1, double num2, double& result)
{
	result = num1 - num2;
	printf("[sub] num1 = %lf, num2 = %lf, result = %lf\n", num1, num2, result);
	return SOAP_OK;
}

/*乘法的具体实现*/
int ns__mult(struct soap* soap, double num1, double num2, double& result)
{
	result = num1 * num2;
	printf("[mul] num1 = %lf, num2 = %lf, result = %lf\n", num1, num2, result);
	return SOAP_OK;
}

/*除法的具体实现*/
int ns__divid(struct soap* soap, double num1, double num2, double& result)
{
	result = num1 / num2;
	printf("[div] num1 = %lf, num2 = %lf, result = %lf\n", num1, num2, result);
	return SOAP_OK;
}

编译运行

会出现如下界面,点击“允许访问”即可。
在这里插入图片描述
这样,我们的第一个 Web Service 服务端程序已经运行起来。
在这里插入图片描述

访问测试

我们可以打开浏览器,输入 localhost:8080 来确定 Web Service 是否正常启动。我们就会看到如下显示。
在这里插入图片描述
这样我们的服务端就已经完成了。
同时我们也可以看到连接信息。
在这里插入图片描述

第一个 Web Service 客户端

该客户端可以向服务端发送申请查询。

建立目录

我们使用 gClient 目录。
在这里插入图片描述

建立项目

还是使用 VS 2019 建立一个控制台应用。这次我们的名字叫 gClient。在这里插入图片描述
在这里插入图片描述

拷贝服务文件

将 gservice.h 拷贝到对应目录。

生成 wsdl 文件

注意这里需要使用参数 C,表示是客户端。

soapcpp2.exe -C gservice.h
D:\gsoap-2.8\gsoap\gClient>soapcpp2.exe -C gservice.h

**  The gSOAP code generator for C and C++, soapcpp2 release 2.8.119
**  Copyright (C) 2000-2021, Robert van Engelen, Genivia Inc.
**  All Rights Reserved. This product is provided "as is", without any warranty.
**  The soapcpp2 tool and its generated software are released under the GPL.
**  ----------------------------------------------------------------------------
**  A commercial use license is available from Genivia Inc., contact@genivia.com
**  ----------------------------------------------------------------------------

Saving soapStub.h annotated copy of the source interface header file
Saving soapH.h serialization functions to #include in projects
Using ns service name: gservice
Using ns service style: rpc
Using ns service encoding: literal
Using ns schema namespace: http://tempuri.org/ns.xsd
Saving gservice.wsdl Web Service description
Saving gservice.add.req.xml sample SOAP/XML request
Saving gservice.add.res.xml sample SOAP/XML response
Saving gservice.sub.req.xml sample SOAP/XML request
Saving gservice.sub.res.xml sample SOAP/XML response
Saving gservice.mult.req.xml sample SOAP/XML request
Saving gservice.mult.res.xml sample SOAP/XML response
Saving gservice.divid.req.xml sample SOAP/XML request
Saving gservice.divid.res.xml sample SOAP/XML response
Saving gservice.nsmap namespace mapping table
Saving ns.xsd XML schema
Saving soapClient.cpp client call stub functions
Saving soapClientLib.cpp client stubs with serializers (use only for libs)
Saving soapC.cpp serialization functions

Compilation successful

项目中加入必须文件

将stdsoap2.h、soapStub.h、soapH.h、gservice.nsmap和stdsoap2.cpp、soapC.cpp、soapClient.cpp文件导入到gClient中,项目目录结构如下

在这里插入图片描述

修改 gClient.cpp

增加 soap 代码

#include <stdio.h>
#include "../soapH.h"
#include "../gservice.nsmap"

int main(int argc, char* argv[])
{
	printf("The Client is runing...\n");
	double num1 = 110;
	double num2 = 11;
	double result = 0;

	struct soap* CalculateSoap = soap_new();
	//soap_init(CalculateSoap);
	char server_addr[] = "http://localhost:8080";

	int iRet = soap_call_ns__add(CalculateSoap, server_addr, "", num1, num2, result);
	if (iRet == SOAP_ERR)
	{
		printf("Error while calling the soap_call_ns__add");
	}
	else
	{
		printf("Calling the soap_call_ns__add success。\n");
		printf("%lf + %lf = %lf\n", num1, num2, result);
	}

	iRet = soap_call_ns__sub(CalculateSoap, server_addr, "", num1, num2, result);
	if (iRet == SOAP_ERR)
	{
		printf("Error while calling the soap_call_ns__sub");
	}
	else
	{
		printf("Calling the soap_call_ns__sub success。\n");
		printf("%lf - %lf = %lf\n", num1, num2, result);
	}

	iRet = soap_call_ns__mult(CalculateSoap, server_addr, "", num1, num2, result);
	if (iRet == SOAP_ERR)
	{
		printf("Error while calling the soap_call_ns__mult");
	}
	else
	{
		printf("Calling the soap_call_ns__mult success。\n");
		printf("%lf * %lf = %lf\n", num1, num2, result);
	}

	iRet = soap_call_ns__divid(CalculateSoap, server_addr, "", num1, num2, result);
	if (iRet == SOAP_ERR)
	{
		printf("Error while calling the soap_call_ns__divid");
	}
	else
	{
		printf("Calling the soap_call_ns__divid success。\n");
		printf("%lf / %lf = %lf\n", num1, num2, result);
	}
	soap_end(CalculateSoap);
	soap_done(CalculateSoap);
	free(CalculateSoap);

	return 0;
}

编译运行

在这里插入图片描述

如上图,我们这样通过 Web Service 实现了相关的计算。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的老周

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值