动环监控系统中B接口的实现-c语言版

10 篇文章 0 订阅

B接口是使用http+xml+ftp形成的一套通讯框架,一般使用gsoap库来开发

首先是准备gsoap库,编译方法这里就不细说了,这里稍微说下用法
开发环境是ubuntu 64位,测试环境是也是ubuntu64位
gsoap 用的是2.8.22
编译完成后,会生成wsdl2h,soapcpp2两个应用程序

动环监控官方给了我两个wsdl文件,分别是客户端和服务端的
FSUService.wsdl
LSCService.wsdl

这里只说设备端怎么做,如果想知道其它,欢迎留言

1.使用wsdl2h工具,根据WSDL产生头文件FSUService.h,执行以下命令
wsdl2h -c -s FSUService.wsdl
-c为产生纯c代码
-s为不使用STL库
详情可通过wsdl2h.exe -help查看帮助。

2.使用soapcpp2工具,根据头文件 FSUService.h 产生框架代码,执行以下命令
soapcpp2 -2 -c FSUService.h
-2 生成 SOAP 1.2
-c 为产生纯c代码,默认生成 c++代码

这有个小细节,要注意gsoap库的版本,前后端不一致就会有问题

将生成的文件复制到自己的工程
soapClient.c
soapH.h
soapServer.c
LSCServiceSoapBinding.nsmap
soapStub.h

写一个server.c作为服务端

#include "soapH.h"
#include "stdsoap2.h"
#include "FSUServiceSoapBinding.nsmap"
int main()
{
 		SOAP_SOCKET master,slave;
    	struct soap *soap=soap_new();
    	soap->send_timeout=5;
    	soap_set_namespaces(soap,namespaces);//之前看到某个教程服务端竟然没写,经过实验证明,不加就是找死
    	soap->bind_flags|=SO_REUSEADDR;// 这里有个bug,绑定的时候竟然没有使用地址重绑定,如果反复启动几回就会出现绑定失败的情况,这句话是通过源码分析得出的使用方法
        master=soap_bind(soap,NULL,30376,100);
    	while(1)
    	{
        		slave=soap_accept(soap);
        		if(slave<0)
       			{
            		continue;
        		}
        		soap_serve(soap);
        		soap_end(soap);
    	}
    	soap_destroy(soap);
    	soap_done(soap);
    	free(soap);
}
//下面这坨是我自己的业务代码
SOAP_FMAC5 int SOAP_FMAC6 ns1__invoke(struct soap *soap, char *_xmlData, char **_invokeReturn)
{
    *_invokeReturn="ooxx";
    return SOAP_OK;
}
    ```

下面是客户端client.c的代码,一看就知道是抄别人的,没办法,懒嘛,不过我可是加工过的

int main(int argc, char **argv)
{

struct soap *fsuSoap = soap_new();
fsuSoap->send_timeout = fsuSoap->recv_timeout = 5;    
struct ns1__invokeResponse soap_tmp_ns1__invokeResponse;
char * soap_tmp_SOAP_ENC__string;
soap_default_ns1__invokeResponse(fsuSoap, &soap_tmp_ns1__invokeResponse);
soap_tmp_SOAP_ENC__string = NULL;
soap_tmp_ns1__invokeResponse._invokeReturn = &soap_tmp_SOAP_ENC__string;

char xmlData[500];
memset(xmlData, 0x00, sizeof(xmlData));
strcat(xmlData, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
strcat(xmlData, "<Request>\n");
strcat(xmlData, "<PK_Type>\n");
strcat(xmlData, "<Name>GET_DATA</Name>\n");
strcat(xmlData, "</PK_Type>\n");
strcat(xmlData, "<Info>\n");
strcat(xmlData, "<FSUID/>\n");
strcat(xmlData, "<DeviceList>\n");
strcat(xmlData, "<Device ID=\"303\">\n");
strcat(xmlData, "</Device>\n");
strcat(xmlData, "</DeviceList>\n");
strcat(xmlData, "</Info>\n");
strcat(xmlData, "</Request>\n");

printf("soap_tmp_ns1__invoke._xmlData:\n");
printf("%s", xmlData);
int iRet = soap_call_ns1__invoke(fsuSoap, NULL, NULL, xmlData, 	                soap_tmp_ns1__invokeResponse._invokeReturn);
if ( iRet == SOAP_ERR)
{
    printf("Error while calling the soap_call_ns1__invoke");
}
else
{
     //这里有个坑,如果程序的xml有问题是会返回500的,如果连接异常是会返回28的,如果namespace异常就是SOAP_CLI_FAULT,这鬼demo也是没谁了,这里我只能判断_invokeReturn不为空才是正经回复
    printf("Calling the soap_call_ns1__invoke success?ret=%d\n",iRet);
    if(*soap_tmp_ns1__invokeResponse._invokeReturn
    	printf("%s\n", *soap_tmp_ns1__invokeResponse._invokeReturn);
}

return 0;

}

客户端和服务端编译就是这么简单
gcc client.c soapC.c soapClient.c -lgsoap -o client
gcc server.c soapC.c soapServer.c -lgsoap -o server

流程就是这么个流程,但是

服务端收不到呀,经过排查发现,soapClient.c发送的时候会带一个SOAP-ENV:Body这样的鬼玩意,服务端则是判断有没有ns__invoke这个字段,就是说发送的xml对于接收端来说,是异端,由于代码是自动生成的,所以还需要修改下soapClient.c
找到这一对代码并删除,就可以了,具体是哪一对嘛,就是connect下面的,我比较懒,就不细说了,聪明的你一看就能明白,蠢笨如我是讲不明白的
soap_body_begin_out(soap)
soap_body_end_out(soap)

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值