用C++ ulxmlrpcpp 做服务端,PHP xmlrpc 做客户端,实现前后xml通信
来源:互联网 发布:html5程序员 表白网页 编辑:程序博客网 时间:2024/06/05 07:20
前一阵,想在fedora下用C++服务程序,PHP前台程序,实现一个系统。选择封装完整HTTP协议通信,且实现多线程的程序库:ulxmlrpcpp。但是这个库只封装c++的客户端和服务端,所以决定在客户端使用PHP xml-rpc。然而两个库并不能完全通信,需要修改一些源码(只修改ulxmlrpcpp代码,所以需要重新编译ulxmlrpcpp,而phpxmlrpc不需要修改)。
1.程序下载:(linux)
ulxmlrpcpp-1.7.5:http://download.csdn.net/detail/liuzhengjian123/4497109
expat-2.1.0:http://download.csdn.net/detail/liuzhengjian123/4497115
phpxmlrpc-3.0.0:http://download.csdn.net/detail/liuzhengjian123/4497119
2.程序安装:(linux)
ulxmlrpcpp和expat的安装都是使用命令:
./confingure
make
make install
注意:安装ulxmlrpcpp前需要先安装expat,还要修改部分代码(详细参考后面)。
phpxmlrpc无需安装,只要将lib目录下的三个文件xmlrpc.inc、xmlrpcs.inc和xmlrpc_wrappers.inc放到php包含目录下即可。如果只编写客户端程序,那么只需要xmlrpc.inc就够了。
3.ulxmlrpcpp代码修改:
1)ulxr_config.h文件:添加如下宏定义,或注释部分宏
- #define ULXR_VERSION "1.7.5"
- #define ULXR_DATADIR "./"
- //#define ULXR_UNICODE 1
- #define ULXR_ENFORCE_NON_PERSISTENT
- //else
- //setPersistent(true);
1.修改之前可能会根本无法通信,首先要编写好ulxmlrpcpp后台程序,添加调用函数。编写PHP前台程序,注意调用相应的函数,主机名 和端口:ulxmlrpcpp配置文件如下:
- # IP for xmlrpc server
- xmlrpc_ip = localhost
- # Port for xmlrpc server
- xmlrpc_port = 32005
- wbxml = 0
- ssl = 0
- secure = 0
- chunked = 0
- shutdown = 0
- persistent = 0
- (13)Permission denied
- # setsebool -P httpd_can_network_connect 1
2.代码调试正确之后,可能会出现服务端可以收到调用请求,但是而且回答也正常发送,但是前台PHP无法解析回答的xml,而求PHP页面一直在等待,超时后才结束。错误代码:
- Code: 2 Reason: 'Invalid return payload: enable debugging to examine incoming payload (XML error: Invalid document end at line 2, column 1)'
- ---GOT---
- HTTP/1.1 200 OK<span style="white-space:pre"> </span> ------------------(第一个回复包,看上去正常)
- Proxy-Connection: Keep-Alive
- Content-Type: text/xml
- Content-Length: 130
- X-Powered-By: ulxmlrpcpp/1.7.5
- Server: localhost
- Date: Mon Aug 13 20:15:57 2012
- <?xml version="1.0" encoding="utf-8"?><methodResponse><params><param><value><i4>23</i4></value></param></params></methodResponse>
- HTTP/1.1 200 OK --------------------(第二个回复包,超时错误提示)
- Connection: Keep-Alive
- Content-Type: text/xml
- Content-Length: 306
- X-Powered-By: ulxmlrpcpp/1.7.5
- Server: localhost
- Date: Mon Aug 13 20:16:07 2012
- <?xml version="1.0" encoding="utf-8"?><methodResponse><fault><value><struct><member><name>faultCode</name><value><i4>500</i4></value></member><member><name>faultString</name><value><string>Timeout while attempting to read (using select).</string></value></member></struct></value></fault></methodResponse>
- ---END---
5.代码:
1)前台php示例代码:client.php
- <html>
- <head><title>xmlrpc</title></head>
- <body>
- <h1>Getstatename demo</h1>
- <h2>Send a U.S. state number to the server and get back the state name</h2>
- <h3>The code demonstrates usage of the php_xmlrpc_encode function</h3>
- <?php
- include("xmlrpc.inc");
- // Play nice to PHP 5 installations with REGISTER_LONG_ARRAYS off
- if(!isset($HTTP_POST_VARS) && isset($_POST))
- {
- $HTTP_POST_VARS = $_POST;
- }
- if(isset($HTTP_POST_VARS["stateno"]) && $HTTP_POST_VARS["stateno"]!="")
- {
- $stateno=(integer)$HTTP_POST_VARS["stateno"];
- $f=new xmlrpcmsg('testcall_in_class_dynamic',
- array(php_xmlrpc_encode($stateno))
- );
- print "<pre>Sending the following request:\n\n" . htmlentities($f->serialize()) . "\n\nDebug info of server data follows...\n\n";
- $c=new xmlrpc_client("./RPC2", "localhost", 32005);
- $c->setDebug(1);
- $r=&$c->send($f);
- echo htmlentities($r->serialize());
- if(!$r->faultCode())
- {
- $v=$r->value();
- print "</pre><br/>State number " . $stateno . " is "
- . htmlspecialchars($v->scalarval()) . "<br/>";
- // print "<HR>I got this value back<BR><PRE>" .
- // htmlentities($r->serialize()). "</PRE><HR>\n";
- }
- else
- {
- print "An error occurred: ";
- print "Code: " . htmlspecialchars($r->faultCode())
- . " Reason: '" . htmlspecialchars($r->faultString()) . "'</pre><br/>";
- }
- }
- else
- {
- $stateno = "";
- }
- print "<form action=\"test.php\" method=\"POST\">
- <input name=\"stateno\" value=\"" . $stateno . "\"><input type=\"submit\" value=\"go\" name=\"submit\"></form>
- <p>Enter a state number to query its name</p>";
- ?>
- <hr/>
- <em>$Id: client.php 2 2009-03-16 20:22:51Z ggiunta $</em>
- </body>
- </html>
- #include <ulxmlrpcpp/ulxmlrpcpp.h> // always first header
- #include <cstring>
- #include <cstdlib>
- #include <ulxmlrpcpp/ulxr_tcpip_connection.h> // first, don't move: msvc #include bug
- #include <ulxmlrpcpp/ulxr_ssl_connection.h>
- #include <ulxmlrpcpp/ulxr_http_protocol.h>
- #ifdef __WIN32__
- #include <process.h>
- #endif
- #include "util.c"
- #ifdef ULXR_MULTITHREADED
- #ifdef __unix__
- #include <pthread.h>
- #endif
- #endif
- #include <iostream>
- #include <cstring>
- #include <memory>
- #include <ulxmlrpcpp/ulxr_except.h>
- #include <ulxmlrpcpp/ulxr_signature.h>
- #include <ulxmlrpcpp/ulxr_mtrpc_server.h>
- #ifdef __WIN32__
- const unsigned num_threads = 10;
- #else
- const unsigned num_threads = 100;
- #endif
- ////////////////////////////////////////////////////////////////////////
- #ifdef ULXR_MULTITHREADED
- ulxr::MultiThreadRpcServer *mtServer = 0;
- class TestWorker
- {
- public:
- TestWorker ()
- {
- }
- ulxr::MethodResponse numThreads (const ulxr::MethodCall &/*calldata*/)
- {
- ulxr::MethodResponse resp;
- resp.setResult(ulxr::Integer(mtServer->numThreads()));
- return resp;
- }
- ulxr::MethodResponse shutdown (const ulxr::MethodCall &/*calldata*/)
- {
- ULXR_COUT << ULXR_PCHAR("TestWorker got signal to shut down\n");
- ulxr::MethodResponse resp;
- resp.setResult(ulxr::Boolean(true));
- ULXR_COUT << ULXR_PCHAR(" Terminating..\n");
- mtServer->terminateAllThreads();
- ULXR_COUT << ULXR_PCHAR(" Returning..\n");
- return resp;
- }
- ulxr::MethodResponse testcall (const ulxr::MethodCall &calldata)
- {
- ulxr::Integer I = calldata.getParam(0);
- int p1 = I.getInteger();
- ULXR_COUT << ULXR_PCHAR("TestWorker got call(") << p1 << ULXR_PCHAR(") \n");
- ulxr::MethodResponse resp;
- resp.setResult(I);
- return resp;
- }
- };
- #endif // ULXR_MULTITHREADED
- ////////////////////////////////////////////////////////////////////////
- int main(int argc, char **argv)
- {
- #ifdef ULXR_MULTITHREADED
- try
- {
- ulxr::intializeLog4J(argv[0]);
- ulxr::getLogger4J()->send(ULXR_PCHAR("DEBUG"),
- ULXR_PCHAR("mt_server started"),
- ULXR_GET_STRING(__FILE__),
- __LINE__);
- ulxr::CppString host = ULXR_PCHAR("localhost");
- if (argc > 1)
- host = ULXR_GET_STRING(argv[1]);
- unsigned port = 32005;
- if (argc > 2)
- port = ulxr_atoi(argv[2]);
- bool wbxml = haveOption(argc, argv, "wbxml");
- bool secure = haveOption(argc, argv, "ssl");
- bool chunked = haveOption(argc, argv, "chunked");
- bool shutme = haveOption(argc, argv, "shutdown");
- bool persistent = haveOption(argc, argv, "persistent");
- ulxr::CppString sec = ULXR_PCHAR("unsecured");
- if (secure)
- sec = ULXR_PCHAR("secured");
- ULXR_COUT << ULXR_PCHAR("Serving ") << sec << ULXR_PCHAR(" rpc requests at ") << host << ULXR_PCHAR(":") << port << std::endl;
- ULXR_COUT << ULXR_PCHAR("WBXML: ") << wbxml << std::endl
- << ULXR_PCHAR("Chunked transfer: ") << chunked << std::endl;
- std::auto_ptr<ulxr::TcpIpConnection> conn;
- #ifdef ULXR_INCLUDE_SSL_STUFF
- if (secure)
- {
- ulxr::SSLConnection *ssl = new ulxr::SSLConnection (true, host, port);
- ssl->setCryptographyData("password", "foo-cert.pem", "foo-cert.pem");
- conn.reset(ssl);
- }
- else
- #endif
- #ifdef _MSC_VER
- {
- std::auto_ptr<ulxr::TcpIpConnection> temp(new ulxr::TcpIpConnection (true, host, port));
- conn = temp;
- }
- #else
- conn.reset(new ulxr::TcpIpConnection (true, host, port));
- #endif
- std::auto_ptr<ulxr::HttpProtocol> prot(new ulxr::HttpProtocol(conn.get()));
- prot->setChunkedTransfer(chunked);
- prot->setPersistent(persistent);
- if (persistent)
- conn->setTcpNoDelay(true);
- if (prot->isPersistent())
- ULXR_COUT << ULXR_PCHAR("Using persistent connections\n") ;
- else
- ULXR_COUT << ULXR_PCHAR("Using non-persistent connections\n") ;
- ulxr::MultiThreadRpcServer server(prot.get(), num_threads, wbxml);
- mtServer = &server;
- TestWorker worker;
- server.addMethod(ulxr::make_method(worker, &TestWorker::testcall),
- ulxr::Signature(ulxr::Struct()),
- ULXR_PCHAR("testcall_in_class_dynamic"),
- ulxr::Signature(ulxr::Integer()),
- ULXR_PCHAR("Testcase with a dynamic method in a class"));
- server.addMethod(ulxr::make_method(worker, &TestWorker::shutdown),
- ulxr::Signature(ulxr::Boolean()),
- ULXR_PCHAR("testcall_shutdown"),
- ulxr::Signature(),
- ULXR_PCHAR("Testcase with a dynamic method in a class, shut down server, return old state"));
- server.addMethod(ulxr::make_method(worker, &TestWorker::numThreads),
- ulxr::Signature(ulxr::Integer()),
- ULXR_PCHAR("testcall_numthreads"),
- ulxr::Signature(),
- ULXR_PCHAR("Returns number of installed threads at startup"));
- unsigned started = server.dispatchAsync();
- ULXR_COUT << ULXR_PCHAR("Started ") << started << ULXR_PCHAR(" threads for dispatching rpc requests\n");
- if (shutme)
- {
- ULXR_COUT << ULXR_CHAR("sleep before shutting down\n");
- #ifdef __unix__
- usleep(5 * 1000 * 1000);
- #elif defined(__WIN32__)
- Sleep(5 * 1000);
- #else
- #error platform not supported
- #endif
- ULXR_COUT << ULXR_CHAR("shutdownAllThreads\n");
- server.shutdownAllThreads();
- }
- server.waitAsync(false, true);
- ULXR_COUT << ULXR_PCHAR("Done.\n");
- }
- catch(ulxr::Exception& ex)
- {
- ULXR_COUT << ULXR_PCHAR("Error occured: ") << ULXR_GET_STRING(ex.why()) << std::endl;
- return 1;
- }
- catch(...)
- {
- ULXR_COUT << ULXR_PCHAR("Unknown error occured\n");
- return 1;
- }
- ULXR_COUT << ULXR_PCHAR("Ready.") << std::endl;
- #else // ULXR_MULTITHREADED
- ULXR_COUT << ULXR_PCHAR("Multithreaded support disabled.");
- #endif
- return 0;
- }
本文重点就是第3点的代码修改,虽然需要修改的地方并不是很多,但是也让我花了好长时间去分析ulxmlrpcpp源代码,才找出错误原因的,希望能给大家带来一些帮助。
原文地址:http://blog.csdn.net/liuzhengjian123/article/details/7861625
- 用C++ ulxmlrpcpp 做服务端,PHP xmlrpc 做客户端,实现前后xml通信
- 用C++ ulxmlrpcpp 做服务端,PHP xmlrpc 做客户端,实现前后xml通信
- quick-cocos做客户端,golang做服务端,实现HTTP通信
- Android做客户端,Web做服务端(Xml数据格式)
- 用Zend Framework做XmlRpc
- 用as3 serverSocket 做服务端,实现web客户端
- C#做服务器,客户端,实现局域网通信
- android客户端同php服务端进行XML/JSON通信
- Java做Socket服务端与Delphi做Socket客户端的通信
- linux xmlrpc 服务端 java客户端
- php做推送服务端实现ios消息推送
- php做推送服务端实现android消息推送
- php做推送服务端实现ios消息推送
- php做推送服务端实现android消息推送
- php做推送服务端实现ios消息推送
- C语言实现服务端和客户端进行TCP通信实例
- C语言实现服务端和客户端进行TCP通信实例
- 【socket】用PHP的socket实现客户端到服务端的通信
- VB FSO.GetSpecialFolder 参数说明
- 你们有没有在一起:伤感日志
- HTML <input> 标签的 type 属性
- 请求重定向与请求转发
- Messagebox.Show()常用参数
- 用C++ ulxmlrpcpp 做服务端,PHP xmlrpc 做客户端,实现前后xml通信
- 触屏网页设计初探1
- LINUX的日子
- 算法参考
- 解决ASP中的Response.Flush不起作用的办法
- run placement fails for object ".far", size 0x100b3c (page 0). Available
- SQL语言总结
- install mod_security
- windows8无法完整安装windows phone sdk 7.1