C++与Java的webservice通信方式实现

C++与Java的一种webservice通信方式实现记录直接分享了.  代码工程

C++采用gsoap库来实现的,在gsoap的SDK中可以找到两个将接口生成代码框架的工具,soapcpp2.exe  wsdl2h.exe

服务端例子add.h

//gsoap ns service name: add
//gsoap ns service namespace: http://localhost/add.wsdl
//gsoap ns service location: http://localhost
//gsoap ns service executable: add.cgi
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:add

int ns__add(int a, int b, int *result);
int ns__sub(double a, double b, double *result);
int ns__mul(double a, double b, double *result);
int ns__div(double a, double b, double *result);
int ns__pow(double a, double b, double *result);
//int ns__checkLogin(char* Name,char* Pass, bool *result);
//int ns__TestShow(int *id, char* *result);
int ns__ClsP(int *result);
int ns__HahaKd(int *result);  
int ns__EndExe(char* Name, int *result); 
int ns__StartExe(char* Name, int *result);

服务端代码:


#include "DCSoap.h"
//输出DBdata的soap
//#include "Soap/soapH.h"
//#include "Soap/DBdata.h"
//输出add的soap
/*#include "lib/add.nsmap"*/
#include "../Soap/soapH.h"
#include "../Soap/add.h"

#include <iostream>

using namespace std;

#define BACKLOG (100)    /* Max. request backlog */
DWORD WINAPI process_request(LPVOID*);
int http_get(struct soap * soap);


DWORD WINAPI process_request(LPVOID* soap) 
{
	soap_serve((struct soap*)soap);
	soap_destroy((struct soap*)soap);
	soap_end((struct soap*)soap);
	soap_done((struct soap*)soap);
	free(soap);
	return 0;
}

int http_get(struct soap * soap) 
{
	FILE *fd = NULL;

	cout<<"call http_get."<<endl;	//printf("call http_get.\n");
	char *s = strchr(soap->path, '?');
	if ( !s || strcmp(s, "?wsdl") ) return SOAP_GET_METHOD;

	//fopen_s(&fd,"DBdata.wsdl", "rb");
	fopen_s(&fd,"add.wsdl", "rb");
	//fd = fopen("add.wsdl", "rb");		//vc6
	if ( !fd ) return 404;

	soap->http_content = "text/xml";
	soap_response(soap, SOAP_FILE);

	for ( ; ; ) {
		size_t r = fread(soap->tmpbuf, 1, sizeof(soap->tmpbuf), fd);
		if ( !r ) break;
		if ( soap_send_raw(soap, soap->tmpbuf, r) ) break;
	}

	fclose(fd);
	soap_end_send(soap);

	return SOAP_OK;
}

int main(int Cport)
{
	struct soap soap;
	struct soap *tsoap;
	const char* fmt = "accepts socket %d connection from IP %d.%d.%d.%d\n";

	soap_init(&soap);

	int port;
	port = Cport; //atoi(argv[1]); 
	cout<<"OPEN HTTP://127.0.0.1:"<<Cport<<endl;  //printf("OPEN HTTP://127.0.0.1:80 \n", Cport);

	soap.send_timeout = 60;
	soap.recv_timeout = 60;
	soap.accept_timeout = 3600;
	soap.max_keep_alive = 100;

	soap.fget = http_get;

	DWORD tid;
	HANDLE hThread;

	//int port = atoi(argv[1]); // first command-line arg is port
	SOAP_SOCKET m, s;

	m = soap_bind(&soap, NULL, port, BACKLOG);
	if ( !soap_valid_socket(m) ) 
	{
		cout<<"Sorry! The port is userd!"<<endl;
		//exit(1);
		return 0;
	}

	cout<<"Socket connection successful "<<m<<endl;		//	
	for ( ; ; ) 
	{
		s = soap_accept(&soap);
		if ( !soap_valid_socket(s) ) 
		{
			if ( soap.errnum ) 
			{
				soap_print_fault(&soap, stderr);
				//exit(1);
				return 0;
			}
			cout<<"server timed out"<<endl;			//printf("server timed out\n");
			break;
		}

		printf(fmt, s, (soap.ip>>24)&0xFF, (soap.ip>>16)&0xFF, (soap.ip>>8)&0xFF, soap.ip&0xFF);

		tsoap = soap_copy(&soap); // make a safe copy
		if ( !tsoap ) break;

		hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)process_request, tsoap, 0, &tid);
		if ( hThread == NULL ) 
		{
			cout<<"can not create a thread for SOAP request processing."<<endl;
			//printf("can not create a thread for SOAP request processing.\n");
			//exit(-1);
			return 0;
		}
	}

	soap_done(&soap);
	return 0;
}

HANDLE SoapThreadHandle;		
DWORD SoapThreadID;
void TheardSoapSvr(int Cport)
{
	SoapThreadHandle=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)StartSoapServer,(void*)Cport,0,&SoapThreadID);
	CloseHandle(SoapThreadHandle);  //上面线程完成后自动释放线程
}

void EndTheardSoapSvr(void)
{
	//ExitThread(SoapThreadHandle);
}

生成wsdl接口文件的方法:

rem wsdl2h.exe: 编译wsdl文件生成c/c++头文件
rem -o 文件名,指定输出头文件 
rem -n 名空间前缀 代替默认的ns 
rem -c 产生纯C代码,否则是C++代码 
rem -s 不要使用STL代码 
rem -t 文件名,指定type map文件,默认为typemap.dat 
rem -e 禁止为enum成员加上名空间前缀
rem soapcpp2.exe: gSOAP编译器,
rem 编译头文件生成服务器和客户端都需要的c/c++文件
rem -C 仅生成客户端代码 
rem -S 仅生成服务器端代码 
rem -L 不要产生soapClientLib.c和soapServerLib.c文件 
rem -c 产生纯C代码,否则是C++代码(与头文件有关) 
rem -I 指定import路径(见上文) 
rem -x 不要产生XML示例文件 
rem -i 生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)

attrib +r +h +s add.cpp
attrib +r +h +s add.h
del *.xml
del *.o
del *.h
del *.cpp
del *.nsmap
del *.xsd
del *.wsdl
rd /s /q client
rem 生成服务端代码
rem gsoap\bin\win32\soapcpp2.exe  -S -I gsoap\import Csoap\lib\add.h
gsoap\bin\win32\soapcpp2.exe add.h
rem gsoap\bin\win32\soapcpp2.exe -i add.h

rem 生成客户端代码
md client
copy /Y add.h .\client\
rem gsoap\bin\win32\wsdl2h.exe -o client\add.h add.wsdl
rem #gsoap\bin\win32\soapcpp2.exe -C -I gsoap\import client\add.h
rem #gsoap\bin\win32\wsdl2h.exe -o add.h ..\..\exe\add.wsdl
attrib -r -h -s add.cpp
attrib -r -h -s add.h
@copy /Y add.wsdl ..\exe\
pause

这里客户端请求 我还是用C++代码(java的应该很常见了) 

客户端就是拿到wsdl接口文件去生成代码了

@echo off
rem wsdl2h.exe: 编译wsdl文件生成c/c++头文件
rem -o 文件名,指定输出头文件 
rem -n 名空间前缀 代替默认的ns 
rem -c 产生纯C代码,否则是C++代码 
rem -s 不要使用STL代码 
rem -t 文件名,指定type map文件,默认为typemap.dat 
rem -e 禁止为enum成员加上名空间前缀
rem soapcpp2.exe: gSOAP编译器,
rem 编译头文件生成服务器和客户端都需要的c/c++文件
rem -C 仅生成客户端代码 
rem -S 仅生成服务器端代码 
rem -L 不要产生soapClientLib.c和soapServerLib.c文件 
rem -c 产生纯C代码,否则是C++代码(与头文件有关) 
rem -I 指定import路径(见上文) 
rem -x 不要产生XML示例文件 
rem -i 生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)
@echo off
del *.xml
del *.o
del *.h
del *.cpp
del *.nsmap
del *.xsd
del *.wsdl
cls
@echo on
copy /Y ..\..\exe\add.wsdl .\add.wsdl
..\..\Soap\gsoap\bin\win32\wsdl2h.exe -o add.h add.wsdl
..\..\Soap\gsoap\bin\win32\soapcpp2.exe  -C -I ..\..\Soap\gsoap\import add.h
pause

客户端调用例子

// SoapClientConsole.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "SoapClient/soapH.h"
#include "SoapClient/soapStub.h"
#include "SoapClient/add.nsmap"
#include <string>
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	//int ns__add(int a, int b, int *result);
	struct soap TestSoap;
	soap_init(&TestSoap);
	int result = -1;
	_ns2__add input;
	input.a = 1;
	input.b = 1;
	input.soap = &TestSoap;
	_ns2__addResponse output;
	output.soap = &TestSoap;

	soap_call___ns1__add(&TestSoap,"http://127.0.0.1:80?wsdl",NULL,&input,&output);     //"http://127.0.0.1:80?wsdl"

	if(TestSoap.error)
	{
		printf("soap error:%d,%s,%s\n", TestSoap.error, *soap_faultcode(&TestSoap), *soap_faultstring(&TestSoap) );
		result = TestSoap.error;
	} 
	else
	{
		cout<<"Return     = "<<*output.result<<endl;
	}

	soap_end(&TestSoap);
	soap_done(&TestSoap);
	system("pause");
	return 0;
}

最后运行测试一下  只要IP对上跨机器通信也好使了.

完整编译代码工程

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值