1 /*=============================================================================
2                         pstream_client.cpp
3 ===============================================================================
4   This is an example of a client that uses XML-RPC for C/C++
5   (Xmlrpc-c).
6 
7   In particular, it uses the simple "packet stream" XML transport mechanism
8   instead of HTTP as specified by XML-RPC (so this is not an XML-RPC
9   client).
10 
11   You have to supply as Standard Input a stream (TCP) socket whose other
12   end is hooked up to the RPC server.  The 'socketexec' program is a
13   good way to arrange that.
14 
15   The sample program pstream_serial_server.cpp is compatible with this client.
16 
17   Example:
18 
19     $ socketexec -connect -remote_host=localhost -remote_port=8080 \
20         ./pstream_client
21 =============================================================================*/
22 
23 #include <cassert>
24 #include <cstdlib>
25 #include <string>
26 #include <iostream>
27 #include <unistd.h>
28 #include <signal.h>
29 
30 using namespace std;
31 
32 #include <xmlrpc-c/girerr.hpp>
33 #include <xmlrpc-c/base.hpp>
34 #include <xmlrpc-c/client.hpp>
35 #include <xmlrpc-c/client_transport.hpp>
36 
37 
38 
39 int
main(int argc,char **)40 main(int argc, char **) {
41 
42     if (argc-1 > 0) {
43         cerr << "This program has no arguments" << endl;
44         exit(1);
45     }
46 
47 #ifndef _WIN32
48     // It's a good idea to disable SIGPIPE signals; if server closes his end
49     // of the pipe/socket, we'd rather see a failure to send a call than
50     // get killed by the OS.
51     signal(SIGPIPE, SIG_IGN);
52 #endif
53 
54     try {
55         xmlrpc_c::clientXmlTransport_pstream myTransport(
56             xmlrpc_c::clientXmlTransport_pstream::constrOpt()
57             .fd(STDIN_FILENO));
58 
59         xmlrpc_c::client_xml myClient(&myTransport);
60 
61         string const methodName("sample.add");
62 
63         xmlrpc_c::paramList sampleAddParms;
64         sampleAddParms.add(xmlrpc_c::value_int(5));
65         sampleAddParms.add(xmlrpc_c::value_int(7));
66 
67         xmlrpc_c::rpcPtr myRpcP(methodName, sampleAddParms);
68 
69         xmlrpc_c::carriageParm_pstream myCarriageParm;
70             // Empty; transport doesn't need any information
71 
72         myRpcP->call(&myClient, &myCarriageParm);
73 
74         assert(myRpcP->isFinished());
75 
76         int const sum(xmlrpc_c::value_int(myRpcP->getResult()));
77             // Assume the method returned an integer; throws error if not
78 
79         cout << "Result of RPC (sum of 5 and 7): " << sum << endl;
80 
81     } catch (exception const& e) {
82         cerr << "Client threw error: " << e.what() << endl;
83     } catch (...) {
84         cerr << "Client threw unexpected error." << endl;
85     }
86 
87     return 0;
88 }
89