gSOAP教程之创建独立(多线程)服务器与客户端调用服务器(二)

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

工具:gsoap-2.8.66(这个是目前各个公司使用最多的,也是最完善的)

系统环境:Centos7 64位

步骤:

1.手动编写calc.h文件

//gsoap ns service name:            calc Simple calculator service described at https://www.genivia.com/dev.html
//gsoap ns service protocol:        SOAP
//gsoap ns service style:           rpc
//gsoap ns service encoding:        encoded
//gsoap ns service namespace:       http://localhost/calc.wsdl
//gsoap ns service location:        http://localhost/calcserver.cgi

//gsoap ns schema namespace:        urn:calc

//gsoap ns service method: add Sums two values
int ns__add(double a, double b, double &result);

//gsoap ns service method: sub Subtracts two values
int ns__sub(double a, double b, double &result);

//gsoap ns service method: mul Multiplies two values
int ns__mul(double a, double b, double &result);

//gsoap ns service method: div Divides two values
int ns__div(double a, double b, double &result);

//gsoap ns service method: pow Raises a to b
int ns__pow(double a, double b, double &result);

2.使用soapcpp2工具生成客户端所需文件(执行命令之前先删除上一个教程所生成的文件):

  ./soapcpp2 -j -r -CL calc.h

  gSOAP教程之创建独立(多线程)服务器与客户端调用服务器(二)_第1张图片

3.编写calcclient.cpp客户端代码:

#include "soapcalcProxy.h"
#include "calc.nsmap"

/* the Web service endpoint URL */
const char server[] = "http://localhost:8080";

int main(int argc, char **argv)
{
  if (argc < 4)
  {
    fprintf(stderr, "Usage: [add|sub|mul|div|pow] num num\n");
    exit(0);
  }
  calcProxy calc(server);
  double a, b, result;
  a = strtod(argv[2], NULL);
  b = strtod(argv[3], NULL);
  switch (*argv[1])
  {
    case 'a':
      calc.add(a, b, result);
      break;
    case 's':
      calc.sub(a, b, result);
      break;
    case 'm':
      calc.mul(a, b, result);
      break;
    case 'd':
      calc.div(a, b, result);
      break;
    case 'p':
      calc.pow(a, b, result);
      break;
    default:
      fprintf(stderr, "Unknown command\n");
      exit(0);
  }
  if (calc.soap->error)
    calc.soap_stream_fault(std::cerr);
  else
    std::cout << "result = " << result << std::endl;
  calc.destroy(); /* clean up */
  return 0;
}

4.执行编译命令生成客户端程序:

  c++ -o calcclient calcclient.cpp soapC.cpp soapcalcProxy.cpp /home/webservice/gsoap-2.8/gsoap/stdsoap2.cpp

  注: /home/webservice/gsoap-2.8/gsoap/ 是stdsoap2.cpp的具体路径

5.使用soapcpp2工具生成服务端所需文件:

  ./soapcpp2 -j -r -SL calc.h

   gSOAP教程之创建独立(多线程)服务器与客户端调用服务器(二)_第2张图片

6.编写calcserver.cpp服务端代码:

#include 
#include "soapcalcService.h"
#include "calc.nsmap"
#include "threads.h" 

int port = 8080;

void *process_request(void *arg)
{
  calcService *service = (calcService*)arg;
  THREAD_DETACH(THREAD_ID);
  if (service)
  {
    service->serve();
    service->destroy(); /* clean up */
    delete service;
  }
  return NULL;
}

 
int main()
{
  calcService service(SOAP_IO_KEEPALIVE);                      /* enable HTTP kee-alive */
  service.soap->send_timeout = service.soap->recv_timeout = 5; /* 5 sec socket idle timeout */
  service.soap->transfer_timeout = 30;                         /* 30 sec message transfer timeout */
  SOAP_SOCKET m = service.bind(NULL, port, 100);              /* master socket */
  if (soap_valid_socket(m))
  {
    while (soap_valid_socket(service.accept()))
    {
      THREAD_TYPE tid;
      void *arg = (void*)service.copy();
      /* use updated THREAD_CREATE from plugin/threads.h https://www.genivia.com/files/threads.zip */
      if (arg)
        while (THREAD_CREATE(&tid, (void*(*)(void*))process_request, arg))
          sleep(1);
    }
  }
  //service.soap_stream_fault(std::err);
  service.destroy(); /* clean up */
  return 0;
}

/* service operation function */
int calcService::add(double a, double b, double &result)
{
  result = a + b;
  return SOAP_OK;
} 
/* service operation function */
int calcService::sub(double a, double b, double &result)
{
  result = a - b;
  return SOAP_OK;
} 
/* service operation function */
int calcService::mul(double a, double b, double &result)
{
  result = a * b;
  return SOAP_OK;
} 
/* service operation function */
int calcService::div(double a, double b, double &result)
{
  if (b)
    result = a / b;
  else
    return soap_senderfault("Division by zero", NULL);
  return SOAP_OK;
} 
/* service operation function */
int calcService::pow(double a, double b, double &result)
{
  result = ::pow(a, b);
  if (soap_errno == EDOM)   /* soap_errno is like errno, but portable */
    return soap_senderfault("Power function domain error", NULL);
  return SOAP_OK;
}

7.执行编译命令生成服务端程序:

   c++ -o calcserver calcserver.cpp -I/home/webservice/gsoap-2.8/gsoap -I/home/webservice/gsoap-2.8/gsoap/plugin /home/webservice/gsoap-2.8/gsoap/stdsoap2.cpp soapC.cpp soapcalcService.cpp -pthread

  注:-I/home/webservice/gsoap-2.8/gsoap  是stdsoap2.h 的具体路径  -I/home/webservice/gsoap-2.8/gsoap/plugin 是threads.h的具体路径  /home/webservice/gsoap-2.8/gsoap 是stdsoap2.cpp的具体路径

8.启动服务端程序:

   ./calcserver

9.启动客户端程序:

   ./calcclient add 10 20

   result = 30;

   c482640fc3868ded821a067e0380c321ad4.jpg

   至此,本篇教程结束,完成了创建独立(多线程)服务器,客户端调用服务器的整个过程。

  感谢阅读,能读到这里,说明你真的是个好学的程序员。

   转载请注明出处。

  

 

转载于:https://my.oschina.net/u/3183495/blog/1841940

你可能感兴趣的:(gSOAP教程之创建独立(多线程)服务器与客户端调用服务器(二))