XMLRPC的C++代碼在下載后的ros_comm-noetic-develutilitiesxmlrpcpp路徑下。
還好,整個(gè)工程不算太大。XMLRPC分成客戶端和服務(wù)器端兩大部分。
咱們先看客戶端,主要代碼在XmlRpcClient.cpp文件里。
擒賊先擒王,XmlRpcClient.cpp文件中最核心的函數(shù)就是execute,用于執(zhí)行遠(yuǎn)程調(diào)用,代碼如下。
// Execute the named procedure on the remote server.
// Params should be an array of the arguments for the method.
// Returns true if the request was sent and a result received (although the result might be a fault).
bool XmlRpcClient::execute(const char* method, XmlRpcValue const& params, XmlRpcValue& result)
{
XmlRpcUtil::log(1, "XmlRpcClient::execute: method %s (_connectionState %s).", method, connectionStateStr(_connectionState));
// This is not a thread-safe operation, if you want to do multithreading, use separate
// clients for each thread. If you want to protect yourself from multiple threads
// accessing the same client, replace this code with a real mutex.
if (_executing)
return false;
_executing = true;
ClearFlagOnExit cf(_executing);
_sendAttempts = 0;
_isFault = false;
if ( ! setupConnection())
return false;
if ( ! generateRequest(method, params))
return false;
result.clear();
double msTime = -1.0; // Process until exit is called
_disp.work(msTime);
if (_connectionState != IDLE || ! parseResponse(result)) {
_header = "";
return false;
}
// close() if server does not supports HTTP1.1
// otherwise, reusing the socket to write leads to a SIGPIPE because
// the remote server could shut down the corresponding socket.
if (_header.find("HTTP/1.1 200 OK", 0, 15) != 0) {
close();
}
XmlRpcUtil::log(1, "XmlRpcClient::execute: method %s completed.", method);
_header = "";
_response = "";
return true;
}
它首先調(diào)用setupConnection()函數(shù)與服務(wù)器端建立連接。
連接成功后,調(diào)用generateRequest()函數(shù)生成發(fā)送請(qǐng)求報(bào)文。
XMLRPC請(qǐng)求報(bào)文的頭部又交給generateHeader()函數(shù)做了,代碼如下。
// Prepend http headers
std::string XmlRpcClient::generateHeader(size_t length) const
{
std::string header =
"POST " + _uri + " HTTP/1.1rn"
"User-Agent: ";
header += XMLRPC_VERSION;
header += "rnHost: ";
header += _host;
char buff[40];
std::snprintf(buff,40,":%drn", _port);
header += buff;
header += "Content-Type: text/xmlrnContent-length: ";
std::snprintf(buff,40,"%zurnrn", length);
return header + buff;
}
主體部分則先將遠(yuǎn)程調(diào)用的方法和參數(shù)變成XML格式,generateRequest()函數(shù)再將頭部和主體組合成完整的報(bào)文,如下:
std::string header = generateHeader(body.length());
_request = header + body;
把報(bào)文發(fā)給服務(wù)器后,就開始靜靜地等待。
一旦接收到服務(wù)器返回的報(bào)文后,就調(diào)用parseResponse函數(shù)解析報(bào)文數(shù)據(jù),也就是把XML格式變成純凈的數(shù)據(jù)格式。
我們發(fā)現(xiàn),XMLRPC使用了socket功能實(shí)現(xiàn)客戶端和服務(wù)器通信。
我們搜索socket這個(gè)單詞,發(fā)現(xiàn)它原始的意思是插座。這非常形象,建立連接實(shí)現(xiàn)通信就像把插頭插入插座。
雖說XMLRPC也是ROS的一部分,但它畢竟只是一個(gè)基礎(chǔ)功能,我們會(huì)用即可,暫時(shí)不去探究其實(shí)現(xiàn)細(xì)節(jié),
-
客戶端
+關(guān)注
關(guān)注
1文章
306瀏覽量
17553 -
服務(wù)端
+關(guān)注
關(guān)注
0文章
69瀏覽量
7364 -
ROS
+關(guān)注
關(guān)注
1文章
293瀏覽量
18723
發(fā)布評(píng)論請(qǐng)先 登錄
ROS與STM32之間的聯(lián)系
ROS與STM32是如何進(jìn)行通信的
什么是ROS?ROS產(chǎn)生、發(fā)展和壯大的原因和意義
如何實(shí)現(xiàn)一個(gè)ROS服務(wù)端呢
ROS與STM32通信
ROS機(jī)器人操作系統(tǒng)的實(shí)現(xiàn)原理(上)
ROS機(jī)器人操作系統(tǒng)的實(shí)現(xiàn)原理(下)
實(shí)現(xiàn)ARM+ROS(機(jī)器人操作系統(tǒng))之運(yùn)行ROS!
ROS中的序列化實(shí)現(xiàn)
ROS中XMLRPC是什么
節(jié)點(diǎn)是如何調(diào)用XMLRPC的
ROS核心框架介紹
ROS是如何實(shí)現(xiàn)XMLRPC的
評(píng)論