Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2716672
  • 博文数量: 416
  • 博客积分: 10220
  • 博客等级: 上将
  • 技术积分: 4193
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-15 09:47
文章分类

全部博文(416)

文章存档

2022年(1)

2021年(1)

2020年(1)

2019年(5)

2018年(7)

2017年(6)

2016年(7)

2015年(11)

2014年(1)

2012年(5)

2011年(7)

2010年(35)

2009年(64)

2008年(48)

2007年(177)

2006年(40)

我的朋友

分类: C/C++

2007-10-13 11:56:13

For my work, I need to create a client/server interface. The client must be programmed with C/C++ and the server with PHP.

After a quick look on the web, I found two projects of a SOAP C++ library which match with my requirement :
- Easysoap -
- Axis -
- Gsoap -

The main problem with the first one is the lake of maintenance of the project. Maybe there is no bug in it but the "last modification 12-April-2002" scared me a bit.
Despite the excellent reputation of apache's projects, I won't Axis because the requierement of having a webserver (apache) already installed on his computer (which is my case but not everybody).

For PHP, there is no standard version for PHP 4. There is one by default in PHP 5, but I am not ready to switch to this version (I know that I will have the envy to adapt my development with the object model that PHP 5 proposes).
One of the reference for PHP4 is :
- Nusoap - which has been developed using PHP (one file of 224 ko ...)

[Suite:]

The PHP server
It is quite simple.
Download the nusoap program.

Create a php file located on your webserver :

function encrypt($myString) {
return md5("salt".md5($myString));
}

require('nusoap.php');

$server = new soap_server();

$server->configureWSDL('security', 'urn:secure'); // Name of the server & the namespace in order to create the wsdl doc

$server->register("encrypt", // method name
array('symbol' => 'xsd:string'), // input parameters
array('return' => 'xsd:string'), // output parameters
'urn:secure', // namespace
'urn:secure#encrypt'); // SOAP action

$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA)
? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>

I declare the datatype of each variable to avoid mistake about datatypes.

The C client

/path/to/gsoap-linux-2.7/wsdl2h -c -o encrypt.h 

The -c option is used to force the generation in C.
This command creates the include thanks to the wsdl declaration.
In this file, we can find what we declared on the server (C++ style) :

int ns1__encrypt(
std::string symbol,
std::string &return_ // < response parameter
);

If you use C++, you will need the stlvector.h file in your current directory.

/path/to/gsoap-linux-2.7/soapcpp2 -c encrypt.h

Will generate the skeletons, xml sample of the flux ...

List of the files :

soapStub.h header file with data type annotations
soapH.h header file of soapC.cpp
soapC.c SOAP/XML (de)serializers for C/C++ data types
soapClient.c proxy stub routines for remote method calls
soapServer.c skeleton routines for service implementation
securityBinding.nsmap a namespace mapping table for the client application
securityBinding.encrypt.req.xml xml sample of the request
securityBinding.encrypt.res.xml xml sample of the response
encrypt.h the header file declarations
soapsecurityBindingObject.h Proxy class (ie C++) for the service
soapsecurityBindingProxy.h Proxy class (ie C++) for the client
soapClientLib.c  
soapServerLib.c  

Create a encryptclient.c file :

#include "soapH.h" // obtain the generated stub 
#include "securityBinding.nsmap" // obtain the namespace mapping table
#include "stdio.h"

int main() {
struct soap soap; // gSOAP runtime environment
soap_init(&soap); // initialize runtime environment (only once)
char *myVar="sandra";
char *result;
if (soap_call_ns1__encrypt(&soap, NULL, NULL, myVar , &result) == SOAP_OK)
printf("Key encrypted = %s ",result);
else
soap_print_fault(&soap, stderr); // display the SOAP fault message on the stderr stream
soap_end(&soap); // remove deserialized data and clean up
soap_done(&soap); // detach the gSOAP environment
return (0);
}

To compile this wonderful application :
gcc -g -I/path/to/gsoap-linux-2.7 -Wall -o encryptclient encryptclient.c soapC.c soapClient.c /path/togsoap-linux-2.7/stdsoap2.c

The processus for a C++ application is almost the same except that you don't have to use the -c parameter when saopcpp2 and wsdl2h are called.
Generated files will have an other extension (cpp instead of c) and include an proxy (basically a wrapper to use the soap web service).

There is the C++ solution without the proxy :

#include "soapH.h" // obtain the generated stub
#include "securityBinding.nsmap" // obtain the namespace mapping table
#include
#include

using namespace std;
int main() {
struct soap soap; // gSOAP runtime environment
soap_init(&soap); // initialize runtime environment (only once)
std::string myVar="sandra";
std::string result;
if (soap_call_ns1__encrypt(&soap, NULL, NULL, myVar , result) == SOAP_OK)
cout << "Key encrypted = " << result;
else
soap_print_fault(&soap, stderr); // display the SOAP fault message on the stderr stream
soap_destroy(&soap); // delete deserialized class instances (for C++ only)
soap_end(&soap); // remove deserialized data and clean up
soap_done(&soap); // detach the gSOAP environment
}

With the proxy (smaller & cleaner isn't it ?) :

#include "soapsecurityBindingProxy.h" /* get the gSOAP-generated proxy */
#include "securityBinding.nsmap" /* get service namespace bindings */
int main() {
securityBinding sec;
string result;
if (sec.ns1__encrypt(string("sandra"), result) == SOAP_OK)
cout << "Key encrypted = " << result;
else
soap_print_fault(sec.soap, stderr);
}

For both sources, the compilation command is :

g++ -I/path/to/license/gsoap-linux-2.7 -Wall -o encryptclient encryptclient.cpp soapC.cpp soapClient.cpp /path/to/gsoap-linux-2.7/stdsoap2.cpp

If you want to use SSL (without prior authentication), just add this

if (soap_ssl_client_context(&soap,SOAP_SSL_NO_AUTHENTICATION,NULL,NULL,NULL,NULL,NULL)) {
soap_print_fault(&soap, stderr);
exit(1);
}

and change the URL (https instead of http) in soapClient.{c/cpp]

URL = "";

And add :

-DWITH_OPENSSL -lssl -lcrypto

to gcc/g++.

Bonus - The client in Python with SOAPpy - :

#!/usr/bin/python
import SOAPpy
try:
server = SOAPpy.SOAPProxy("")
print server.encrypt("sandra")
except Exception, e:
print """Error : %s """% e
Sources :
Tutorial - Nusoap with PHP4 :
gSOAP User Guide :
Creating a C/C++ client for a WebSphere Web service using WebSphere Studio Application Developer, gSOAP, and Dev-C++ : http://www-900.ibm.com/developerWorks/cn/wsdd/library/techarticles/0301_lin/lin_eng.shtm 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1329786

阅读(1552) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~