首页 > 生活万象知识

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件举报,一经查实,本站将立刻删除。