由于项目需要,要实现webserver客户端和已经提供的上位机软件通信,这个软件是别人已经写好的,其本身可以看做是webserver的服务端,服务端开发者提供了一个.wsdl文件,这是一个服务器描述语言,里面给了我们客户端需要的接口。在C/C++中,实现webserver的工具就是gSoap。所需工具和源程序在链接中。
gSoap2.8工具:点击打开链接
客户端和服务端源码:点击打开链接
解压下面链接所给的soap压缩文件,在路径gsoap-2.8\gsoap\bin\win32找到Wsdl2h.exe和soapcpp2.exe。 Wsdl2h.exe是专门解析wsdl文件,生成客户端和服务端所需的头文件的工具,而wsdl文件是web服务描述语言,这个文件一般是有服务开发者提供,因为我们写的是c/c++程序,所以头文件的生成可以自己编写(前提是我们已经知道服务端的接口类型即函数接口类型)。
首先打开控制台(cmd)进入上述工具所在文件夹(cdC:\**\***Desktop\webs),将wsdl文件拷贝到此目录下,执行命令wsdl2h.exe -o xx.h xx.wsdl ,生成所需的接口头文件。
将生成或者自己编写的头文件在控制台中执行语句 soapcpp2.exe xx.h ,根据接口头文件生成应用程序客户端和服务端的框架文件(soapClient.cpp、soapServer.cpp等).
一服务器端
1.首先编写 calc.h文件:函数定义ns__不能缺少
//gsoap ns service name: cal
//gsoap ns service namespace: http://localhost/add.wsdl
//gsoap ns service location: http://localhost
//gsoap ns service executable: cal.cgi
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:cal
int ns__add( int num1, int num2, int* sum );
int ns__sub( int num1, int num2, int* result)
2. 用 gsoap/bin 目录下的 soapcpp2.exe 程序,生成一些文件。可以把 soapcpp2.exe 拷贝到一 add.h 目录下,用 cmd 执行 soapcpp2.exe add.h 就可以,在这个目录下会自动生成许多将来有用的文件,如 cal.namap,soapH.h,soapC.cpp,soapClient.cpp,soapServer.cpp 等文件。 soapcpp2.exe 可以带参数执行,具体执行 soapcpp2.exe -h 查看。 #include "stdio.h"
#include "soapH.h"
#include "add.nsmap"
int main(int argc, char **argv)
{
int listenPort = 8090;//访问端口号
int backlog = 100;//最大访问量
SOAP_SOCKET nMaster, nSlave;
struct soap soap;//新建soap
soap_init(&soap);//初始化soap
nMaster = soap_bind(&soap, NULL, listenPort, backlog);//绑定地址,端口,访问量
if (nMaster < 0)
{
soap_print_fault(&soap, stderr);
exit(-1);
}
fprintf(stderr, "Socket connection successful : master socket = %d\n", nMaster);
while (true)
{
nSlave = soap_accept(&soap);
if (nSlave < 0)
{
soap_print_fault(&soap, stderr);
exit(-1);
}
fprintf(stderr, "Socket connection successful : slave socket = %d\n", nSlave);
soap_serve(&soap);
soap_end(&soap);
}
return 0;
}
/*加法的具体实现server端的实现函数与add.h中声明的函数相同,但是多了一个当前的soap连接的参数*/
int ns__add(struct soap *soap, int num1, int num2, int* result)
{
if (NULL == result)
{
printf("Error:The third argument should not be NULL!\n");
return SOAP_ERR;
}
else
{
(*result) = num1 + num2;
return SOAP_OK;
}
return SOAP_OK;
}
/*减法的具体实现*/
int ns__sub(struct soap *soap, int num1, int num2, int* result)
{
if (NULL == result)
{
printf("Error:The third argument should not be NULL!\n");
return SOAP_ERR;
}
else
{
(*result) = num1 - num2;
return SOAP_OK;
}
return SOAP_OK;
}
在ie中输入localhost:8090,如果显示xml页面,说明程序已经启动。
4. 客户端设计,需要添加一下文件文件。Client.cpp,cal.nsmap,soapC.cpp,soapClient.cpp,soapH.h,stdsoap2.cpp,
stdsoap2.h.
#include "stdio.h"
#include "GSoapServer.nsmap"
int main(int argc, char *argv[])
{
printf("The Client is runing...\n");
int num1 = 110;
int num2 = 11;
int result = 0;
struct soap *CalculateSoap = soap_new();
//soap_init(CalculateSoap);
char * server_addr = "http://localhost:8090";
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("%d + %d = %d\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("%d - %d = %d\n", num1, num2, result);
}
soap_end(CalculateSoap);
soap_done(CalculateSoap);
free(CalculateSoap);
system("pause");
return 0;
}
我是在vs2013下编译这个两个文件,整个webserver的实现也很简单,功能也就是实现简单的加减法,在服务端写好函数的实现,在客户端调用,本来是打算客户端手动输入两个任意数进行加减法,但是因为懒,就直接省略了,而是在客户端直接把值给指定了,直接在控制台上输出结果。
写文章时参考很多前辈的教程,在此就不一一列举了,本人萌新,有些表达可能不够准确,如果错误,也请前辈们批评指正。