Table Of Contents

Introduction

XML-RPC for C/C++ is a software package of programming libraries to help a C or C++ program use XML-RPC. In particular, a C/C++ programmer can easily write a program to be an XML-RPC client or server.

XML-RPC for C/C++ is also known as Xmlrpc-c.

What is XML-RPC?

XML-RPC is a standard network protocol that computers can use to talk to each other in a remote procedure call fashion. Remote procedure call essentially means that a program on one computer runs a program on another computer. But a simpler way of looking at this kind of network protocol is just that you have client and servers. A client makes individual isolated requests of A server. A server sits around waiting for a request to arrive from some client, does what the request asks, and sends a response. It then goes back to waiting for the next request.

Here are some examples of remote procedure call (RPC) style communications:

Here are some kinds of communication that are not RPC:

The original RPC protocol is the Sun RPC protocol -- the one that NFS (the network fileystem protocol) uses. The Sun RPC protocol is layered over UDP or sometimes TCP and uses a machine-friendly bits and bytes format, just like the TCP/IP layers under it.

XML-RPC differs from Sun RPC in that it encodes the information in the requests and responses in XML. That means they are human friendly -- XML is human-readable ASCII text, so a human can readily see what's going on from a network trace and quickly write code to create and decipher XML-RPC streams. Of course, the tradeoff is that XML-RPC uses way more network and computation resources than Sun RPC. Because XML-RPC is meant to be used for relatively small and infrequent transactions, this is thought not to matter.

In XML-RPC, the aforementioned XML is transported via HTTP (the protocol whose principle purpose is to implement web serving -- web browsing is a form of RPC, after all). HTTP is normally carried over TCP, which is carried over IP.

There are lots of servers in the world that use the XML-RPC protocol and lots of programs and programming libraries from which people can build XML-RPC-based servers and clients.

There are also other HTTP-based RPC protocols. SOAP and CORBA are the most famous.

For more information on XML-RPC, see The XML-RPC web site.

How Does XML-RPC For C/C++ Help with XML-RPC?

The function libraries in XML-RPC For C/C++ (Xmlrpc-c) let you write a program that makes XML-RPC calls (a client) or executes XML-RPC calls (a server program) at any of various levels of understanding of the XML-RPC protocol.

Here are some examples of client and server code.

The Xmlrpc-c Function Libraries

This is a list of the function libraries Xmlrpc-c provides, with links to the manual for each.

Appendices

Introductory Examples

Here, to show you what Xmlrpc-c is, we present example code (almost an entire C program) for a simple XML-RPC client that exploits the Xmlrpc-c libraries, and a corresponding simple XML-RPC server.

You can find complete working versions of these, and lots of other examples in the examples/ directory in the Xmlrpc-c source tree.

In these examples, the service to be provided is adding of two numbers. You wouldn't do this with RPC in real life, of course, because a program can add two numbers without the help of a remote server. This is just to demonstrate the concept.

Small Client Example

Here is an example of C code that implements an XML-RPC client using the highest level facilities of Xmlrpc-c. This client sends a request to add 5 and 7 together to an XMLRPC-C server that is designed to provide the service of adding numbers.


#include <xmlrpc.h>
#include <xmlrpc_client.h>

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

#define NAME "XML-RPC C Test Client"
#define VERSION "1.0"

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

    xmlrpc_env env;
    xmlrpc_value *result;
    int sum;
    char * const url = "http://localhost:8080/RPC2";
    char * const methodName = "sample.add";

    /* Initialize our error-handling environment. */
    xmlrpc_env_init(&env);

    /* Start up our XML-RPC client library. */
    xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0);
    die_if_fault_occurred(&env);

    /* Make the remote procedure call */
    result = xmlrpc_client_call(&env, url, methodName,
                "(ii)", (xmlrpc_int32) 5, (xmlrpc_int32) 7);
    die_if_fault_occurred(&env);
    
    /* Get our state name and print it out. */
    xmlrpc_parse_value(&env, result, "i", &sum);
    die_if_fault_occurred(&env);
    printf("The sum  is %d\n", sum);
    
    /* Dispose of our result value. */
    xmlrpc_DECREF(result);

    /* Clean up our error-handling environment. */
    xmlrpc_env_clean(&env);
    
    /* Shutdown our XML-RPC client library. */
    xmlrpc_client_cleanup();

    return 0;
}


Small Server Example

Now, here is code that implements an XML-RPC server that provides this number-adding service:


#include <xmlrpc.h>
#include <xmlrpc_abyss.h>

static xmlrpc_value *
sample_add(xmlrpc_env *   const env, 
           xmlrpc_value * const param_array, 
           void *         const user_data) {

    xmlrpc_int32 x, y, z;

    /* Parse our argument array. */
    xmlrpc_parse_value(env, param_array, "(ii)", &x, &y);
    if (env->fault_occurred)
        return NULL;

    /* Add our two numbers. */
    z = x + y;

    /* Return our result. */
    return xmlrpc_build_value(env, "i", z);
}



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

    if (argc-1 != 1) {
        fprintf(stderr, "You must specify 1 argument:  The Abyss " 
                "configuration file name.  You specified %d.\n",  argc-1);
        exit(1);
    }

    xmlrpc_server_abyss_init(XMLRPC_SERVER_ABYSS_NO_FLAGS, argv[1]);
    xmlrpc_server_abyss_add_method("sample.add", &sample_add, NULL);

    printf("server: switching to background.\n");
    xmlrpc_server_abyss_run();

    /* We never reach this point. */
    return 0;
}

There's a lot going on under the covers of this example server. What the xmlrpc_server_abyss_run() statement does is start a whole HTTP server. The HTTP server runs the abyss web server (i.e. HTTP server) program. abyss is like the more serious web server program apache, but on a much smaller scale. An XML-RPC call is just an HTTP POST request, so while abyss was not designed specifically for XML-RPC, it provides much of the function an XML-RPC server needs.

The only way this Abyss web server differs from one you would run to do traditional web serving is that it contains a special handler to call Xmlrpc-c functions to handle an XML-RPC POST request. The server calls that handler for any URI that starts with "/RPC2", which is what XML-RPC URIs conventionally have.

While abyss is distributed independently of xmlrpc-c, xmlrpc-c contains an old copy of it, somewhat modified. So you don't need to install abyss separately.

In this example, you have to provide an example abyss configuration file as a program argument. The main thing you need that file for is to specify on which TCP port the server will listen. A single "Port 8080" statement is probably enough. (I say 8080, because in the example client code above, I hardcoded 8080 as the port in the URI the client uses).

There are lots of other ways to use Xmlrpc-c libraries to build XML-RPC clients and servers. The more code you're willing to write, and the more involved in the guts of the protocol you want to get, the more control you can have.