基于Webservice gSOAP的嵌入式计算器的设计总结
Web Service 是流行的Web应用开发技术,它改变了传统个C/S或者是B/S软件开发的模式。
gSOAP 编译工具提供了一个SOAP/XML 关于C/C++的实现方法,它包含WSDL生成器,可以生成Web服务的解释,也可以把它看做C/C++的Web服务协议栈
该协议栈包含5个部分
1.网络传输
2.Web服务调用(消息传输)
3.Web服务描述和注册(接口描述、发布、与实现)
4.Web服务质量(安全性,可靠性、事务控制)
5.Web服务工作流(商业流程、事务等)
gSOAP工具包中提供了2个可执行文件 wsdl2h和soapcpp2
SOAP(Simple Object Access Protocol ,简单对象访问协议) 包含4个部分:SOAP封装(envelop),SOAP编码规则,SOAP RPC ,SOAP绑定
SOAP协议规范说明中SOAP消息包含3个部分:1.必须的根元素<Envelope> 2.可选的SOAP头<Header> 3.必须的SOAP体<Body>
实现客户端的程序
calcclient.c
#include "soapH.h"
#include "calc.nsmap"
const char server[] ="http://192.168.1.199:8080";
int main(int argc, char **argv)
{ struct soap soap;
double a, b, result;
if (argc < 4)
{ fprintf(stderr, "Usage: [add|sub|mul|div|pow] num num\n");
exit(0);
}
soap_init(&soap);
a = strtod(argv[2], NULL);
b = strtod(argv[3], NULL);
switch (*argv[1])
{ case 'a':
soap_call_ns__add(&soap, server, "", a, b, &result);
break;
case 's':
soap_call_ns__sub(&soap, server, "", a, b, &result);
break;
case 'm':
soap_call_ns__mul(&soap, server, "", a, b, &result);
break;
case 'd':
soap_call_ns__div(&soap, server, "", a, b, &result);
break;
case 'p':
soap_call_ns__pow(&soap, server, "", a, b, &result);
break;
default:
fprintf(stderr, "Unknown command\n");
exit(0);
}
if (soap.error)
{ soap_print_fault(&soap, stderr);
exit(1);
}
else
printf("result = %g\n", result);
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
return 0;
}
实现服务器端的程序
calcserver.c
#include "soapH.h"
#include "calc.nsmap"
int main(int argc, char **argv)
{ int m, s; /* master and slave sockets */
struct soap soap;
soap_init(&soap);
if (argc < 2)
soap_serve(&soap); /* serve as CGI application */
else
{ m = soap_bind(&soap, NULL, atoi(argv[1]), 100);
if (m < 0)
{ soap_print_fault(&soap, stderr);
exit(-1);
}
fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
for ( ; ; )
{ s = soap_accept(&soap);
fprintf(stderr, "Socket connection successful: slave socket = %d\n", s);
if (s < 0)
{ soap_print_fault(&soap, stderr);
exit(-1);
}
soap_serve(&soap);
soap_end(&soap);
}
}
return 0;
}
int ns__add(struct soap *soap, double a, double b, double *result)
{ *result = a + b;
return SOAP_OK;
}
int ns__sub(struct soap *soap, double a, double b, double *result)
{ *result = a - b;
return SOAP_OK;
}
int ns__mul(struct soap *soap, double a, double b, double *result)
{ *result = a * b;
return SOAP_OK;
}
int ns__div(struct soap *soap, double a, double b, double *result)
{ if (b)
*result = a / b;
else
{ char *s = (char*)soap_malloc(soap, 1024);
sprintf(s, "<error xmlns=\"http://tempuri.org/\">Can't divide %f by %f</error>", a, b);
return soap_sender_fault(soap, "Division by zero", s);
}
return SOAP_OK;
}
int ns__pow(struct soap *soap, double a, double b, double *result)
{ *result = pow(a, b);
if (soap_errno == EDOM) /* soap_errno is like errno, but compatible with Win32 */
{ char *s = (char*)soap_malloc(soap, 1024);
sprintf(s, "Can't take the power of %f to %f", a, b);
sprintf(s, "<error xmlns=\"http://tempuri.org/\">Can't take power of %f to %f</error>", a, b);
return soap_sender_fault(soap, "Power function domain error", s);
}
return SOAP_OK;
}
Makefile 文件的代码如下:
GSOAP=../../bin/soapcpp2
SOAPH=../../stdsoap2.h
SOAPC=../../stdsoap2.c
SOAPCPP=../../stdsoap2.cpp
CC=gcc
CPP=g++
LIBS=
COFLAGS=-O2
CWFLAGS=-Wall
CIFLAGS=-I../..
CMFLAGS=
CFLAGS= $(CWFLAGS) $(COFLAGS) $(CIFLAGS) $(CMFLAGS)
all: calcclient calcserver
calcclient: calc.h calcclient.c $(SOAPH) $(SOAPC)
$(GSOAP) -c calc.h
$(CC) $(CFLAGS) -o calcclient calcclient.c soapC.c soapClient.c $(SOAPC) $(LIBS)
calcserver: calc.h calcserver.c $(SOAPH) $(SOAPC)
$(GSOAP) -c calc.h
arm-linux-gcc $(CFLAGS) -o calcserver calcserver.c soapC.c soapServer.c $(SOAPC) -lm $(LIBS)
clean:
rm -f *.o soapH.h soapStub.h soapC.cpp soapC.c soapClient.cpp soapClient.c soapServer.cpp soapServer.c soap*Proxy.h
distclean:
rm -f *.o *.wsdl *.xsd *.xml *.nsmap *.log soapH.h soapStub.h soapC.cpp soapC.c soapClient.cpp soapClient.c soapServer.cpp soapServer.c soap*Proxy.h calcclient calcserver
实验步骤如下:
1.配置交叉编译库arm-linux-gcc
2.解压gsoap_linux_2.7.9e.tar.gz
[root@localhost arm2410cl]# tar -zxvf gsoap_linux_2.7.9e.tar.gz
3. 修改Makefile文件
进入arm2410cl/gsoap-linux-2.7/samples/calc/目录下的文件,
[root@localhost calc]# vi Makefile
找到
calcserver: calc.h calcserver.c $(SOAPH) $(SOAPC)
$(GSOAP) -c calc.h
arm-linux-gcc $(CFLAGS) -o calcserver calcserver.c soapC.c soapServer.c $(SOAPC) -lm $(LIBS)
//将calcserver:中的$(CC)改为arm-linux-gcc编译器
4、修改calcclient.c
[root@localhost calc]# vi calcclient.c
//编辑calc客户端文件,为了能看出效果可以用目录标板的IP地址,将下面的内容:
const char server[] = "http://websrv.cs.fsu.edu/~engelen/calcserver.cgi";
修改成:
const char server[] = “http://192.168.1.199:8080”;
5.编译Makefile文件
[root@localhost calc]# make
//编译原程序代码,在编译的时候会显示一些关于限制范围的一些警告信息,但不会影响运行结果。
6、挂载: U盘 mount /dev/sda1 /mnt/nfs
7、进入/mnt/nfs/ gsoap-linux-2.7/samples/calc/
[/mnt/yaffs] cd /mnt/nfs/ gsoap-linux-2.7/samples/calc/
8、执行交叉编译好的可执行文件
[/mnt/nfs/gsoap-linux-2.7/samples/calc]./calcserver 8080
出现下图表示运行成功
9、在linux打开浏览器,在地址栏输入:http://192.168.1.199:8080/
,显示下面界面,同时也会在目标板显示一个从slave socket接口号4连接成功的信息。
10.执行乘法运算:5 *6=30
[root@localhost calc]# ./calcclient mul 5 6
运行结果如图
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!