• linux下gsoap的初次使用 -- c风格加法实例


    摘自:

    http://blog.csdn.net/jinpw/article/details/3346844

    https://www.cnblogs.com/dkblog/archive/2011/08/19/2145942.html

    这两天,接到一个项目,需要在linux程序中调用远程的web应用,通过soap协议。开始上网查了下资料,发现了gsoap库这个好东东^_^。继续在网上搜索例子代码,发现基本都不可编译通过,于是便一边学习一边写了这个最简单的例子,希望对后来者起到一点帮助。

    • 对gsoap的简单介绍,请自己参阅http://gsoap2.sourceforge.net/

        下载相应的包,主要有2个工具和源代码:
        wsdl2h -o outfile.h infile.wsdl 实现wsdl文件到h文件的数据映射
            
    soapcpp2 -c outfile.h生成相应的底层通信stub,strech程序

    • 下面这个简单的例子实现的是在客户端输入2个数字,然后远程调用服务端的加法函数,最后返回结果给客户端。

        在这里我们不需要wsdl的文件,可以直接从.h文件来生成代码。我们定义一个函数声明文件,用来定义接口函数,名称为add.h,内容如下:

    1. //gsoapopt cw
    2. //gsoap ns2 schema namespace: urn:add
    3. //gsoap ns2 schema form: unqualified
    4. //gsoap ns2 service name: add
    5. //gsoap ns2 service type: addPortType
    6. //gsoap ns2 service port:http://websrv.cs.fsu.edu/~engelen/addserver.cgi
    7. //gsoap ns2 service namespace: urn:add
    8. //gsoap ns2 service transport: http://schemas.xmlsoap.org/soap/http
    9. //gsoap ns2  service method-style:      add rpc
    10. //gsoap ns2  service method-encoding:   
    11. add http://schemas.xmlsoap.org/soap/encoding/
    12. //gsoap ns2  service method-action:     add ""
    13. int ns2__add( int num1, int num2, int* sum );

    然后我们执行soapcpp2 -c add.h,自动生成一些远程调用需要的文件。

    接下来我们写一个服务端,创建文件addserver.c

    1. #include "soapH.h"
    2. #include "add.nsmap"
    3. int main(int argc, char **argv)
    4. {
    5.     int m, s;
    6.     struct soap add_soap;
    7.     soap_init(&add_soap);
    8.     soap_set_namespaces(&add_soap, namespaces);
    9.     if (argc < 2) {
    10.         printf("usage: %s <server_port> /n", argv[0]);
    11.         exit(1);
    12.     } else {
    13.         m = soap_bind(&add_soap, NULL, atoi(argv[1]), 100);
    14.         if (m < 0) {
    15.             soap_print_fault(&add_soap, stderr);
    16.             exit(-1);
    17.         }
    18.         fprintf(stderr, "Socket connection successful: master socket = %d/n", m);
    19.         for (;;) {
    20.             s = soap_accept(&add_soap);
    21.             if (s < 0) {
    22.                 soap_print_fault(&add_soap, stderr);
    23.                 exit(-1);
    24.             }
    25.             fprintf(stderr, "Socket connection successful: slave socket = %d/n", s);
    26.             soap_serve(&add_soap);
    27.             soap_end(&add_soap);
    28.         }
    29.     }
    30.     return 0;
    31. }
    32. int ns2__add(struct soap *add_soap, int num1, int num2, int *sum)
    33. {
    34.     *sum = num1 + num2;
    35.     return 0;
    36. }


    我们接着写客户端,文件addclient.c

    1. #include "soapStub.h"
    2. #include "add.nsmap"
    3. int add(const char *server, int num1, int num2, int *sum)
    4. {
    5.     struct soap add_soap;
    6.     int result = 0;
    7.     soap_init(&add_soap);
    8.     soap_set_namespaces(&add_soap, namespaces);
    9.     soap_call_ns2__add(&add_soap, server, NULL, num1, num2, sum);
    10.     printf("server is %s, num1 is %d, num2 is %d/n", server, num1, num2);
    11.     if (add_soap.error) {
    12.         printf("soap error: %d, %s, %s/n", add_soap.error, *soap_faultcode(&add_soap), *soap_faultstring(&add_soap));
    13.         result = add_soap.error;
    14.     }
    15.     soap_end(&add_soap);
    16.     soap_done(&add_soap);
    17.     return result;
    18. }

    最后写一个测试代码,addtest.c

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <string.h>
    4. int add(const char *server, int num1, int num2, int *sum);
    5. int main(int argc, char **argv)
    6. {
    7.     int result = -1;
    8.     char server[128] = {0};
    9.     int num1;
    10.     int num2;
    11.     int sum;
    12.     if (argc < 4) {
    13.         printf("usage: %s <ip:port> num1 num2 /n", argv[0]);
    14.         exit(1);
    15.     }
    16.     strcpy(server,argv[1]);
    17.     num1 = atoi(argv[2]);
    18.     num2 = atoi(argv[3]);
    19.     result = add(server, num1, num2, ∑);
    20.     if (result != 0) {
    21.         printf("soap error, errcode=%d/n", result);
    22.     } else {
    23.         printf("%d + %d = %d/n", num1, num2, sum);
    24.     }
    25.     return 0;
    26. }

    到此为止,我们自己的代码已经编写完毕,现在我们来编译服务端和客户端
    注意:编译的时候我们需要gsoap包里的源代码文件,把stdsoap2.c和stdsoap2.h文件拷贝到当前目录

    我们写一个Makefile文件:

    1. GSOAP_ROOT = /root/gsoap-2.7/gsoap
    2. WSNAME = add
    3. CC = g++ -g -DWITH_NONAMESPACES
    4. INCLUDE = -I$(GSOAP_ROOT)
    5. SERVER_OBJS = soapC.o stdsoap2.o soapServer.o $(WSNAME)server.o 
    6. CLIENT_OBJS = soapC.o stdsoap2.o soapClient.o $(WSNAME)client.o $(WSNAME)test.o
    7. all: server
    8. server: $(SERVER_OBJS) 
    9.     $(CC) $(INCLUDE) -o $(WSNAME)server $(SERVER_OBJS) 
    10. client: $(CLIENT_OBJS) 
    11.     $(CC) $(INCLUDE) -o $(WSNAME)test $(CLIENT_OBJS)
    12. cl:
    13.     rm -f *.o *.xml *.a *.wsdl *.nsmap soapH.h $(WSNAME)Stub.* $(WSNAME)server ns.xsd $(WSNAME)test

    然后我们执行make,即可生产addserver程序;make client,生成addtest程序。
    让server跑起来,执行./addserver 6666

    终端打印出“Socket connection successful: master socket = 3”,那么你的server已经在前台run起来了;
    运行客户端,./addtest ip:port num1 num2,返回加法的结果。

    OK,一个最简单的soap调用的例子完成了,进深一步的学习请参考http://gsoap2.sourceforge.net/

  • 相关阅读:
    Unity3D启动报错的解决方案
    Unity3D引用dll打包发布的问题及解决
    轻量级C#网络通信组件StriveEngine —— C/S通信开源demo(附源码)
    k8s 各种网络方案
    网络模型
    管理和安装 chart
    开发自己的 chart
    再次实践 MySQL chart
    chart 模板
    chart 目录结构
  • 原文地址:https://www.cnblogs.com/LiuYanYGZ/p/8622390.html
Copyright © 2020-2023  润新知