首页 > 其他分享 >XmlRPC入门_基于组合类型的客户端、服务端

XmlRPC入门_基于组合类型的客户端、服务端

时间:2023-12-01 16:59:54浏览次数:40  
标签:const XmlRPC xmlrpc fault envP value env 服务端 客户端

1、客户端

#include <stdlib.h>
#include <stdio.h>

#include <xmlrpc-c/base.h>
#include <xmlrpc-c/client.h>

#include "config.h"  /* information about this build environment */

#define NAME "Xmlrpc-c Test Client"
#define VERSION "1.0"

static void
dieIfFaultOccurred (xmlrpc_env * const envP) {
    if (envP->fault_occurred) {
        fprintf(stderr, "ERROR: %s (%d)\n",
                envP->fault_string, envP->fault_code);
        exit(1);
    }
}



struct ratio {
    double dividend;
    double divisor;
};



int
main(int           const argc,
     const char ** const argv) {

    const char * const serverUrl = "http://localhost:8080/RPC2";
    const char * const methodName = "example.divide";
    unsigned int const argVersion = 1;
    struct ratio const data[] = {{1,2},{12,3},{10,3},{89,3000}};
    xmlrpc_env env;
    xmlrpc_value * resultP;
    unsigned int i;
    xmlrpc_value * ratioArrayP;
    unsigned int quotientCt;

    if (argc-1 > 0) {
        fprintf(stderr, "This program has no arguments\n");
        exit(1);
    }

    xmlrpc_env_init(&env);

    xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0);
    dieIfFaultOccurred(&env);

    /* Build the 2nd method argument: the array of ratios */

    ratioArrayP = xmlrpc_array_new(&env);
    dieIfFaultOccurred(&env);

    for (i = 0; i < 4; ++i) {
        xmlrpc_value * dividendP;
        xmlrpc_value * divisorP;
        xmlrpc_value * ratioP;

        dividendP = xmlrpc_double_new(&env, data[i].dividend);
        dieIfFaultOccurred(&env);
        divisorP  = xmlrpc_double_new(&env, data[i].divisor);
        dieIfFaultOccurred(&env);

        ratioP = xmlrpc_struct_new(&env);
        dieIfFaultOccurred(&env);

        xmlrpc_struct_set_value(&env, ratioP, "DIVIDEND", dividendP);
        dieIfFaultOccurred(&env);
        xmlrpc_struct_set_value(&env, ratioP, "DIVISOR",  divisorP);
        dieIfFaultOccurred(&env);

        xmlrpc_array_append_item(&env, ratioArrayP, ratioP);
        dieIfFaultOccurred(&env);

        xmlrpc_DECREF(ratioP);
        xmlrpc_DECREF(divisorP);
        xmlrpc_DECREF(dividendP);
    }

    /* Make the call */

    resultP = xmlrpc_client_call(&env, serverUrl, methodName, "(iA)",
                                 (xmlrpc_int32) argVersion, ratioArrayP);
    dieIfFaultOccurred(&env);

    /* Print out the quotients returned */

    quotientCt = xmlrpc_array_size(&env, resultP);
    dieIfFaultOccurred(&env);

    for (i = 0; i < quotientCt; ++i) {
        xmlrpc_value * quotientP;
        xmlrpc_double quotient;

        xmlrpc_array_read_item(&env, resultP, i, &quotientP);
        dieIfFaultOccurred(&env);

        xmlrpc_read_double(&env, quotientP, &quotient);
        dieIfFaultOccurred(&env);

        printf("Server says quotient %u is %f\n", i, quotient);

        xmlrpc_DECREF(quotientP);
    }

    xmlrpc_DECREF(resultP);

    xmlrpc_env_clean(&env);

    xmlrpc_client_cleanup();

    return 0;
}

2、服务端

#define WIN32_LEAN_AND_MEAN  /* required by xmlrpc-c/server_abyss.h */

#include <stdlib.h>
#include <stdio.h>

#include <xmlrpc-c/base.h>
#include <xmlrpc-c/server.h>
#include <xmlrpc-c/server_abyss.h>

#include "config.h"  /* information about this build environment */



static void
computeQuotient(xmlrpc_env *    const envP,
                xmlrpc_value *  const ratioP,
                xmlrpc_double * const quotientP) {

    xmlrpc_value * dividendP;

    xmlrpc_struct_find_value(envP, ratioP, "DIVIDEND", &dividendP);

    if (!envP->fault_occurred) {
        if (!dividendP)
            xmlrpc_env_set_fault(
                envP, 0, "Structure is missing 'DIVIDEND' member");
        else {
            xmlrpc_value * divisorP;

            xmlrpc_struct_find_value(envP, ratioP, "DIVISOR", &divisorP);

            if (!envP->fault_occurred) {
                if (!divisorP)
                    xmlrpc_env_set_fault(
                        envP, 0, "Structure is missing 'DIVISOR' member");
                else {
                    xmlrpc_double dividend;

                    xmlrpc_read_double(envP, dividendP, &dividend);

                    if (!envP->fault_occurred) {
                        xmlrpc_double divisor;

                        xmlrpc_read_double(envP, divisorP, &divisor);

                        if (!envP->fault_occurred)
                            *quotientP = dividend / divisor;
                    }
                    xmlrpc_DECREF(divisorP);
                }
            }
            xmlrpc_DECREF(dividendP);
        }
    }
}



static void
computeQuotients(xmlrpc_env *    const envP,
                 xmlrpc_value *  const ratioArrayP,
                 xmlrpc_value ** const quotientArrayPP) {

    xmlrpc_value * quotientArrayP;

    quotientArrayP = xmlrpc_array_new(envP);
    if (!envP->fault_occurred) {

        unsigned int const ratioCt = xmlrpc_array_size(envP, ratioArrayP);

        unsigned int i;

        for (i = 0; i < ratioCt && !envP->fault_occurred; ++i) {
            xmlrpc_value * ratioP;

            xmlrpc_array_read_item(envP, ratioArrayP, i, &ratioP);

            if (!envP->fault_occurred) {
                xmlrpc_double quotient;

                computeQuotient(envP, ratioP, &quotient);

                if (!envP->fault_occurred) {
                    xmlrpc_value * quotientP;

                    quotientP = xmlrpc_double_new(envP, quotient);

                    if (!envP->fault_occurred) {
                        xmlrpc_array_append_item(envP, quotientArrayP,
                                                 quotientP);

                        xmlrpc_DECREF(quotientP);
                    }
                }
                xmlrpc_DECREF(ratioP);
            }
        }
        if (envP->fault_occurred)
            xmlrpc_DECREF(quotientArrayP);
        else
            *quotientArrayPP = quotientArrayP;
    }
}



static xmlrpc_value *
example_divide(xmlrpc_env *   const envP,
               xmlrpc_value * const paramArrayP,
               void *         const serverInfo,
               void *         const channelInfo) {

    xmlrpc_value * retvalP;
    xmlrpc_int32 argVersion;
    xmlrpc_value * ratioArrayP;

    xmlrpc_decompose_value(envP, paramArrayP, "(iA)",
                           &argVersion, &ratioArrayP);
    if (envP->fault_occurred)
        return NULL;

    if (argVersion != 1) {
        xmlrpc_env_set_fault(envP, 0, "Parameter list version must be 1");
        return NULL;
    }

    computeQuotients(envP, ratioArrayP, &retvalP);

    xmlrpc_DECREF(ratioArrayP);

    if (envP->fault_occurred)
        return NULL;

    return retvalP;
}



int
main(int           const argc,
     const char ** const argv) {

    struct xmlrpc_method_info3 const methodInfo = {
        /* .methodName     = */ "example.divide",
        /* .methodFunction = */ &example_divide,
    };
    xmlrpc_server_abyss_parms serverparm;
    xmlrpc_registry * registryP;
    xmlrpc_env env;

    if (argc-1 != 1) {
        fprintf(stderr, "You must specify 1 argument:  The TCP port "
                "number on which the server will accept connections "
                "for RPCs (8080 is a common choice).  "
                "You specified %d arguments.\n",  argc-1);
        exit(1);
    }

    xmlrpc_env_init(&env);

    registryP = xmlrpc_registry_new(&env);

    xmlrpc_registry_add_method3(&env, registryP, &methodInfo);

    /* In the modern form of the Abyss API, we supply parameters in memory
       like a normal API.  We select the modern form by setting
       config_file_name to NULL:
    */
    serverparm.config_file_name = NULL;
    serverparm.registryP        = registryP;
    serverparm.port_number      = atoi(argv[1]);
    serverparm.log_file_name    = "/tmp/xmlrpc_log";

    printf("Running XML-RPC server...\n");

    xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(log_file_name));

    /* xmlrpc_server_abyss() never returns */

    return 0;
}

标签:const,XmlRPC,xmlrpc,fault,envP,value,env,服务端,客户端
From: https://www.cnblogs.com/missyou0813/p/17870405.html

相关文章

  • XmlRPC入门_基于C的服务端、客户端
    以下客户端与服务端的代码内容为官网给出的示例,此处拷贝记录,了解基础使用方式。1、服务端#include<iostream>#include<winsock2.h>#include<windows.h>#include"xmlrpc-c/base.h"#include"xmlrpc-c/server.h"#include"xmlrpc-c/server_abyss.h"#incl......
  • 个推文档 > 服务端 > C# > 快速入门
    转自:https://docs.getui.com/getui/server/csharp/start/.NETCore版本个推C#SDK支持.NetCore版本,可以到后面的网址去下载的.NetSDK(版本要求>=2.2):(https://dotnet.microsoft.com/download/)下载个推C#Demo, .NETCoredemo 目录结构如下图所示: ......
  • centos上安装redis、redis客户端操作、redis使用场景、通用命令
    centos上安装redis#win上装redis#上线--》centos装了--》详细研究#docker装---》配置--》持久化#官网看看-redis源码-----》自己编译-redisstack----》编译过后的可执行文件-6.x版本#咱们刚刚下了几个软件-redis-6.2.14-reids......
  • XmlRPC入门_组合类型操作
    1、数组操作#include<iostream>#include<winsock2.h>#include<windows.h>#include<xmlrpc-c/base.hpp>#include<xmlrpc-c/registry.hpp>#include<xmlrpc-c/server_abyss.hpp>#include<direct.h>#include<stdio.h&......
  • XmlRPC入门_基本类型操作
    #include<iostream>#include<winsock2.h>#include<windows.h>#include<xmlrpc-c/base.hpp>#include<xmlrpc-c/registry.hpp>#include<xmlrpc-c/server_abyss.hpp>#include<direct.h>#include<stdio.h>#inc......
  • 如何查看redis中当前的客户端连接并且杀掉某些客户端连接
    查看当前的redisclient信息 进入redis控制台,执行命令clientlist  释放(杀掉)某些客户端 执行命令clientkill<客户端地址> 客户端地址,就是上面的addr=的部分 示例:clientkill10.1.40.156:24830  执行正确,会返回OK,表示客户端连接已经被kill掉了......
  • XmlRPC入门_形参定义
    形参类型的定义略Thestringlookssomethinglikethisexample:i:iii,s:.Itisalistofsignaturestrings,separatedbycommas.Intheexample,therearetwosignatures:i:iiis:Eachsignaturestringdescribesoneformofcallingthemethod.Asignatures......
  • 客户端开发工作总结
    1.动机在长达8年的前端工作经验后,发现还是不知道想做啥。自己对技术的掌握还是停留在对数据的展示和存储上。因此先对之前的工作中用到的知识做一个抽象的总结,再思考自己应该去掌握什么技术,又想学什么技术。2.认知客户端开发主要工作即开发UI(userinterface),与用户交互的界面......
  • Nacos源码(三):SpringCloud-Nacos客户端注册源码分析
    1、服务注册源码入口在笔记(二):Nacos环境搭建中提到Nacos作为注册中心,在服务启动类中可通过添加可选配置注解@EnableDiscoveryClient,那么就先从这个注解入手,开启SpringCloud的Nacos注册中心的源码分析。EnableDiscoveryClient注解详情:EnableDiscoveryClientImport......
  • Chat2DB高颜值、免费开源、集成AI的数据库客户端
     Chat2DB是一款有开源免费的多数据库客户端工具,支持windows、mac本地安装,也支持服务器端部署,web网页访问。和传统的数据库客户端软件Navicat、DBeaver相比Chat2DB集成了AIGC的能力,能够将自然语言转换为SQL,也可以将SQL转换为自然语言,可以给出研发人员SQL的优化建......