soapclient,soa*
gsoap 调用webservice内存泄漏
gsoap调用webservice出现内存泄漏
程序运行起来后内存一直增长,出现了内存泄漏,经过各模块的测试分析,将泄漏代码出现在这一段。
/*webservice客户端函数,上传本地数据库数据到远程服务器*/
int
sendtowebservice(char
**data_values,int
n_columns,sqlite3*
conn)
{
char
sql[200]=”
“;
char
*err_msg;
int
res;
struct
soap
*clientsoap
=
soap_new();
soap_cmac
_ns1__sendonemessage
sendmsg;
soap_cmac
_ns1__sendonemessageresponse
sendmsgresponse;
#if
1
soap_init(clientsoap);
sendmsg.grpid=atoi(data_values[0]);
sendmsg.ctime=atoi(data_values[1]);
sendmsg.allencount=atoi(data_values[2]);
sendmsg.alloutcount=atoi(data_values[3]);
printf(“sendmsg.grpid=%d;sendmsg.ctime=%d;sendmsg.encount=%d;sendmsg.outcount=%d\n”,sendmsg.grpid,sendmsg.ctime,sendmsg.allencount,sendmsg.alloutcount);
sprintf_s(buffer,sizeof(buffer),”sendmsg.grpid=%d;sendmsg.ctime=%d;sendmsg.encount=%d;sendmsg.outcount=%d”,sendmsg.grpid,sendmsg.ctime,sendmsg.allencount,sendmsg.alloutcount);
writelog(buffer);
struct
soap_env__header
header;
clientsoap->header=&header;
string
strid(“admin”);
string
strpsw(“123456”);
soap_cmac
ns1__mysoapheader
mysoapheader;
mysoapheader.userid=&strid;
mysoapheader.userpw=&strpsw;
header.ns1__mysoapheader_=&mysoapheader;
clientsoap->header=&header;
if(soap_call___ns1__sendonemessage(clientsoap,
null,
null,
&sendmsg,
&sendmsgresponse)==soap_ok)
{
//printf(“response=%d\n
“,
sendmsgresponse.sendonemessageresult);
sprintf_s(buffer,sizeof(buffer),”sendmsgresponse.sendonemessageresult=%d”,sendmsgresponse.sendonemessageresult);
writelog(buffer);
/*
-1
=验证失败,
-2=失败,1=*成功,2=更新成功;
*成功,更新成功写数据库,将数据标为已发送。
失败,返回-1,上传数据线程释放资源
*/
switch(sendmsgresponse.sendonemessageresult)
{
case
0:
soap_destroy(clientsoap);
soap_end(clientsoap);
soap_done(clientsoap);
return
-1;
break;
case
1:
writelog(“上传到服务器,数据*成功”);
sprintf_s(sql,sizeof(sql),”update
grp
set
issend=%d
where
ctime=%d
and
gropid=%d”,1,atoi(data_values[1]),atoi(data_values[0]));
res=sqlite3_exec(conn,
sql,
null,
0,
&err_msg);
if(res!=sqlite_ok)
{
fprintf(stderr,”*作失败,错误代码:%s”,err_msg);
sprintf_s(buffer,sizeof(buffer),”*作失败,错误代码:%s”,err_msg);
writelog(buffer);
}
else
{
printf(“本地数据issend更新为1成功\n”);
writelog(“本地数据issend更新为1成功”);
}
sqlite3_free(err_msg);
break;
case
2:
writelog(“上传到服务器,数据更新成功”);
sprintf_s(sql,sizeof(sql),”update
grp
set
issend=%d
where
ctime=%d
and
gropid=%d”,1,atoi(data_values[1]),atoi(data_values[0]));
res=sqlite3_exec(conn,
sql,
null,
0,
&err_msg);
if(res!=sqlite_ok)
{
fprintf(stderr,”*作失败,错误代码:%s\n”,err_msg);
sprintf_s(buffer,sizeof(buffer),”*作失败,错误代码:%s”,err_msg);
writelog(buffer);
}
else
{
printf(“本地数据issend更新为1成功\n”);
writelog(“本地数据issend更新为1成功”);
}
sqlite3_free(err_msg);
break;
case
-1:
writelog(“-1,连接服务器验证失败”);
soap_destroy(clientsoap);
soap_end(clientsoap);
soap_done(clientsoap);
return
-1;
break;
case
-2:
writelog(“-2,失败”);
soap_destroy(clientsoap);
soap_end(clientsoap);
soap_done(clientsoap);
VB通过SoapClient调用WS,怎么设置超时
我们都知道,调用WS可以在工程中添加对WS的WEB引用。
但是,如果我们不想通过添加引用的方式,而是在代码中动态引用该怎么办呢看
首先,我们该想到WS的实现也是一个类的形式。
其次,WS在传输过程中是通过WSDL来进行描述的(使用SOAP协议)。
因此,我们需要获取WS的WSDL描述,并通过该描述来动态生成程序集。
最后:通过反射来获取新生成的程序集,并调用其方法!
上述步骤需要引用如下四个名称空间:
using System.Web.Services.Description;//WS的描述
//以下几个用于根据描述动态生成代码并动态编译获取程序集
using System.CodeDom;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
上述几个名称空间中包括如下几个重要的类:
using System.Web.Services.Description下:
ServiceDescription//WS描述
ServiceDescriptionImporter//通过描述生成客户端代理类,特别注意其中的Style
以下是MSDN对其的描述:
XML Web services的接口通常由 Web服务描述语言(WSDL)文件来说明。例如,若要获取有关使用处公开的 ASP.NET的 Web服务的 WSDL说明,只需导航到?WSDL。使用 ServiceDescriptionImporter类可以方便地将 WSDL说明中包含的信息导入到System.CodeDom.CodeCompileUnit对象。通过调整 Style参数的值,可以指示 ServiceDescriptionImporter实例生成客户端代理类(通过透明调用该类可提供 Web服务的功能)或生成抽象类(该类封装 Web服务的功能而不实现该功能)。如果将 Style属性设置为 Client,则 ServiceDescriptionImporter生成客户端代理类,通过调用这些类来提供说明的 Web服务的功能。如果将Style属性设置为 Server,则 ServiceDescriptionImporter实例生成抽象类,这些类表示所说明的 XML Web services的功能而不进行实现。然后,可以通过编写从这些抽象类继承的类来对其进行实现,并实现相关的方法。
using System.CodeDom下:
CodedomUnit//它用于设定动态代码的名称空间,类名等,可以通过ServiceDescriptionImporter.Import()方法将WS的描述代码写入该类,以作动态编译用
using System.CodeDom.Compiler下:
CodedomProvider//用于创建和检索代码生成器和代码编译器的实例,我们主要用到其实现子类CShareCodeProvider
可以直接用CShareCodeProvider provider=new CShareCodeProvider()来生成,或者用CodedomProvider.CreateProvider(“CSharp”)来生成
ICodeCompiler//用于编译基于 System.CodeDom的源代码表示形式。
它通过CodedomProvider的CreateCompiler()方法来
CompilerResults//表示从编译器返回的编译结果。它由ICodeCompiler根据指定的编译器设置从指定的 CodeCompileUnit所包含的 System.CodeDom树中编译程序集并返回。CompiledAssembly属性指示编译的程序集。
了解如上信息后,就可动态调用WS了。
php连接webservice每次都要new SoapClient()吗
最近工作中需要用php调用web service接口,对php不熟,上网搜搜,发现关于用php调用web service的文章也不多,不少还是php4里用nusoap这个模块调用的方法,其实php5里已经包含了处理soap的模块,但是资料太少了,上php*上查帮助,写的不是很容易理解,经过多次实践,终于搞清楚了,php调用web service还是非常简单的。下面用一个例子说明:
web service服务是查询QQ用户是否在线
使用php5开发客户端:
<?php
try{
//$client= new SoapClient(“HelloService.wsdl”,array('encoding'=>'UTF-8'));
$client= new SoapClient(“webservices/qqOnlineWebService.asmx?wsdl”);
var_dump($client->__getFunctions());
print(“”);
var_dump($client->__getTypes());
print(“”);
class qqCheckOnline{
var$qqCode=”10000″;
};
$arrPara= array(new qqCheckOnline);
$arrResult=$client->__Call(“qqCheckOnline”,$arrPara);//$client->qqCheckOnline($arrPara);
echo$arrResult->qqCheckOnlineResult.””;
} catch(SOAPFault$e){
print$e;
}
?>
代码确实很简单吧,创建SoapClient对象时,可以使用保存在本地WSDL文件,也可以使用远程的地址,后面的array数组里可以带上很多的参数,具体参数可以查php的SoapClient帮助,这里带的是字符集编码,如果调用方法的参数里有中文,一定要指定字符集编码,否则会出错。
调用web service前可以先调用SoapClient的__geunctions()和__getTypes()方法看一下你要调用的web service暴露的方法,参数和数据类型,需要注意的是传入的参数名一定要和soapclient里面定义的一致,否则参数是传不过去的。
需要使用SoapClient的__soapCall()或__call()方法,具体使用方法可以查php的帮助文档。如果参数要求是一个结构体,请用类代替,如上面的代码。
另外发现个问题,如果web service方法返回的是xml格式的字符串,php接收到以后会自己把数据内容解析出来,而不是xml字符串.
本文链接:http://www.lanmudan.com/html/87966384.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件举报,一经查实,本站将立刻删除。