YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
NameServer.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
8
9#include <yarp/conf/string.h>
10#include <yarp/conf/version.h>
11
14#include <yarp/os/NetType.h>
15#include <yarp/os/Network.h>
16#include <yarp/os/Port.h>
17#include <yarp/os/Property.h>
18#include <yarp/os/Time.h>
19#include <yarp/os/Value.h>
20#include <yarp/os/Vocab.h>
23
24#include <map>
25#include <set>
26
27using namespace yarp::os::impl;
28using namespace yarp::os;
29
30YARP_OS_LOG_COMPONENT(NAMESERVER, "yarp.os.impl.NameServer")
31
32// produce a correctly parsed string in presence of quoting
33static std::string STR_HELP(const char* txt)
34{
35 Value v;
36 v.fromString(txt);
37 return v.asString();
38}
39#define STR(x) STR_HELP(x).c_str()
40
43//
44// Basic functionality
45//
48
49
50Contact NameServer::unregisterName(const std::string& name)
51{
52 Contact prev = queryName(name);
53 if (prev.isValid()) {
54 if (prev.getPort() != -1) {
55 NameRecord& rec = getNameRecord(prev.getRegName());
56 if (rec.isReusablePort()) {
57 HostRecord& host = getHostRecord(prev.getHost());
58 host.release(prev.getPort());
59 }
60 if (rec.isReusableIp()) {
61 if (rec.getAddress().getCarrier() == "mcast") {
62 mcastRecord.releaseAddress(rec.getAddress().getHost().c_str());
63 }
64 }
65 rec.clear();
66 tmpNames.release(name);
67
68 Bottle event;
69 event.addVocab32("del");
70 event.addString(name.c_str());
71 onEvent(event);
72 }
73 }
74
75 return queryName(name);
76}
77
78
79Contact NameServer::registerName(const std::string& name,
80 const Contact& address,
81 const std::string& remote)
82{
83 bool reusablePort = false;
84 bool reusableIp = false;
85
86 yCTrace(NAMESERVER, "in registerName...");
87
88 if (name != "...") {
89 unregisterName(name);
90 }
91
92 Contact suggestion = address;
93
94 if (!suggestion.isValid()) {
95 suggestion = Contact(name, "...", "...", 0);
96 }
97
98 std::string portName = name;
99 if (portName == "...") {
100 portName = tmpNames.get();
101 }
102
103 std::string carrier = suggestion.getCarrier();
104 if (carrier == "...") {
105 carrier = "tcp";
106 }
107
108 std::string machine = suggestion.getHost();
109 int overridePort = 0;
110 if (machine == "...") {
111 if (carrier != "mcast") {
112 if (remote == "...") {
113 yCError(NAMESERVER, "remote machine name was not found! can only guess it is local...");
114 machine = "127.0.0.1";
115 } else {
116 machine = remote;
117 }
118 } else {
119 machine = mcastRecord.get();
120 overridePort = mcastRecord.lastPortNumber();
121 reusableIp = true;
122 }
123 }
124
125 int port = suggestion.getPort();
126 if (port == 0) {
127 if (overridePort != 0) {
128 port = overridePort;
129 } else {
130 port = getHostRecord(machine).get();
131 reusablePort = true;
132 }
133 }
134
135 suggestion = Contact(portName, carrier, machine, port);
136
137 yCDebug(NAMESERVER, "Registering %s for %s", suggestion.toURI().c_str(), suggestion.getRegName().c_str());
138
139 NameRecord& nameRecord = getNameRecord(suggestion.getRegName());
140 nameRecord.setAddress(suggestion, reusablePort, reusableIp);
141
142 Bottle event;
143 event.addVocab32("add");
144 event.addString(suggestion.getRegName().c_str());
145 onEvent(event);
146
147 return nameRecord.getAddress();
148}
149
150
151Contact NameServer::queryName(const std::string& name)
152{
153 std::string base = name;
154 std::string pat;
155 if (name.find("/net=") == 0) {
156 constexpr size_t patStart = 5;
157 size_t patEnd = name.find('/', patStart);
158 if (patEnd >= patStart && patEnd != std::string::npos) {
159 pat = name.substr(patStart, patEnd - patStart);
160 base = name.substr(patEnd);
161 yCDebug(NAMESERVER, "Special query form %s (%s/%s)", name.c_str(), pat.c_str(), base.c_str());
162 }
163 }
164
165 NameRecord* rec = getNameRecord(base, false);
166 if (rec != nullptr) {
167 if (!pat.empty()) {
168 std::string ip = rec->matchProp("ips", pat);
169 if (!ip.empty()) {
170 auto sip = yarp::conf::string::split(ip, ' ');
171 Contact c = rec->getAddress();
172 c.setHost(sip.at(0));
173 return c;
174 }
175 }
176 return rec->getAddress();
177 }
178 return Contact();
179}
180
181
182NameServer::NameRecord* NameServer::getNameRecord(const std::string& name,
183 bool create)
184{
185 auto entry = nameMap.find(name);
186 if (entry == nameMap.end()) {
187 if (!create) {
188 return nullptr;
189 }
190 nameMap.emplace(name, NameRecord());
191 entry = nameMap.find(name);
192 }
193 yCAssert(NAMESERVER, entry != nameMap.end());
194 return &(entry->second);
195}
196
197
198NameServer::HostRecord* NameServer::getHostRecord(const std::string& name,
199 bool create)
200{
201 auto entry = hostMap.find(name);
202 if (entry == hostMap.end()) {
203 if (!create) {
204 return nullptr;
205 }
206 hostMap[name] = HostRecord();
207 entry = hostMap.find(name);
208 entry->second.setBase(basePort);
209 }
210 yCAssert(NAMESERVER, entry != hostMap.end());
211 return &(entry->second);
212}
213
214
217//
218// Remote interface
219//
222
223
224void NameServer::setup()
225{
226
228
229 dispatcher.add("register", &NameServer::cmdRegister);
230 dispatcher.add("unregister", &NameServer::cmdUnregister);
231 dispatcher.add("query", &NameServer::cmdQuery);
232 dispatcher.add("help", &NameServer::cmdHelp);
233 dispatcher.add("set", &NameServer::cmdSet);
234 dispatcher.add("get", &NameServer::cmdGet);
235 dispatcher.add("check", &NameServer::cmdCheck);
236 dispatcher.add("match", &NameServer::cmdMatch);
237 dispatcher.add("list", &NameServer::cmdList);
238 dispatcher.add("route", &NameServer::cmdRoute);
239 dispatcher.add("gc", &NameServer::cmdGarbageCollect);
240 dispatcher.add("bot", &NameServer::cmdBot);
241 dispatcher.add("announce", &NameServer::cmdAnnounce);
242
243 ndispatcher.add("list", &NameServer::ncmdList);
244 ndispatcher.add("query", &NameServer::ncmdQuery);
245 ndispatcher.add("version", &NameServer::ncmdVersion);
246 ndispatcher.add("set", &NameServer::ncmdSet);
247 ndispatcher.add("get", &NameServer::ncmdGet);
248}
249
250std::string NameServer::cmdRegister(int argc, char* argv[])
251{
252
253 std::string remote = argv[0];
254 argc--;
255 argv++;
256
257 if (argc < 1) {
258 return "need at least one argument";
259 }
260 std::string portName = STR(argv[0]);
261
262 std::string machine = "...";
263 std::string carrier = "...";
264 int port = 0;
265 if (argc >= 2) {
266 carrier = argv[1];
267 }
268 if (argc >= 3) {
269 machine = argv[2];
270 }
271 if (argc >= 4) {
272 if (std::string("...") == argv[3]) {
273 port = 0;
274 } else {
275 port = yarp::conf::numeric::from_string<int>(argv[3]);
276 }
277 }
278
279 Contact address = registerName(portName, Contact(portName, carrier, machine, port), remote);
280
281 yCDebug(NAMESERVER, "name server register address -- %s", address.toString().c_str());
282
283 return terminate(textify(address));
284}
285
286
287std::string NameServer::cmdQuery(int argc, char* argv[])
288{
289 // ignore source
290 argc--;
291 argv++;
292
293 if (argc < 1) {
294 return "need at least one argument";
295 }
296 std::string portName = STR(argv[0]);
297 Contact address = queryName(portName);
298 return terminate(textify(address));
299}
300
301std::string NameServer::cmdUnregister(int argc, char* argv[])
302{
303 // ignore source
304 argc--;
305 argv++;
306
307 if (argc < 1) {
308 return "need at least one argument";
309 }
310 std::string portName = STR(argv[0]);
311 Contact address = unregisterName(portName);
312 return terminate(textify(address));
313}
314
315
316std::string NameServer::cmdAnnounce(int argc, char* argv[])
317{
318 // ignore source
319 argc--;
320 argv++;
321
322 return terminate("ok\n");
323}
324
325std::string NameServer::cmdRoute(int argc, char* argv[])
326{
327 // ignore source
328 argc--;
329 argv++;
330
331 if (argc < 2) {
332 return terminate("need at least two arguments: the source port and the target port\n(followed by an optional list of carriers in decreasing order of desirability)");
333 }
334 std::string src = STR(argv[0]);
335 std::string dest = STR(argv[1]);
336
337 argc -= 2;
338 argv += 2;
339
340 const char* altArgv[] = {
341 "local",
342 "shmem",
343 "mcast",
344 "udp",
345 "tcp",
346 "text"};
347 int altArgc = 6;
348
349 if (argc == 0) {
350 argc = altArgc;
351 argv = (char**)altArgv;
352 }
353
354
355 NameRecord& srcRec = getNameRecord(src);
356 NameRecord& destRec = getNameRecord(dest);
357 std::string pref;
358
359 for (int i = 0; i < argc; i++) {
360 std::string carrier = argv[i];
361 if (srcRec.checkProp("offers", carrier) && destRec.checkProp("accepts", carrier)) {
362 bool ok = true;
363 if (carrier == "local" || carrier == "shmem") {
364 if (srcRec.getProp("ips") == destRec.getProp("ips")) {
365 if (carrier == "local") {
366 if (srcRec.getProp("process") != destRec.getProp("process")) {
367 ok = false;
368 }
369 }
370 } else {
371 ok = false;
372 }
373 }
374 if (ok) {
375 pref = carrier;
376 break;
377 }
378 }
379 }
380 if (!pref.empty()) {
381 pref = pref + ":/" + dest;
382 } else {
383 pref = dest;
384 }
385
386 std::string result = "port ";
387 result += src + " route " + dest + " = " + pref + "\n";
388 return terminate(result);
389}
390
391
392std::string NameServer::cmdHelp(int argc, char* argv[])
393{
394 // ignore source
395 argc--;
396 argv++;
397
398 std::string result = "Here are some ways to use the name server:\n";
399 //ACE_Vector<std::string> names = dispatcher.getNames();
400 //for (unsigned i=0; i<names.size(); i++) {
401 //const std::string& name = names[i];
402 //result += std::string(" ") + name + " ...\n";
403 //}
404 result += std::string("+ help\n");
405 result += std::string("+ list\n");
406 result += std::string("+ register $portname\n");
407 result += std::string("+ register $portname $carrier $ipAddress $portNumber\n");
408 result += std::string(" (if you want a field set automatically, write '...')\n");
409 result += std::string("+ unregister $portname\n");
410 result += std::string("+ query $portname\n");
411 result += std::string("+ set $portname $property $value\n");
412 result += std::string("+ get $portname $property\n");
413 result += std::string("+ check $portname $property\n");
414 result += std::string("+ match $portname $property $prefix\n");
415 result += std::string("+ route $port1 $port2\n");
416 result += std::string("+ gc\n");
417 return terminate(result);
418}
419
420
421std::string NameServer::cmdSet(int argc, char* argv[])
422{
423 // ignore source
424 argc--;
425 argv++;
426
427 if (argc < 2) {
428 return "need at least two arguments: the port name, and a key";
429 }
430 std::string target = STR(argv[0]);
431 std::string key = argv[1];
432 NameRecord& nameRecord = getNameRecord(target);
433 nameRecord.clearProp(key);
434 for (int i = 2; i < argc; i++) {
435 nameRecord.addProp(key, argv[i]);
436 }
437 return terminate(std::string("port ") + target + " property " + key + " = " + nameRecord.getProp(key) + "\n");
438}
439
440std::string NameServer::cmdGet(int argc, char* argv[])
441{
442 // ignore source
443 argc--;
444 argv++;
445
446 if (argc < 2) {
447 return "need exactly two arguments: the port name, and a key";
448 }
449 std::string target = STR(argv[0]);
450 std::string key = argv[1];
451 NameRecord& nameRecord = getNameRecord(target);
452 return terminate(std::string("port ") + target + " property " + key + " = " + nameRecord.getProp(key) + "\n");
453}
454
455std::string NameServer::cmdMatch(int argc, char* argv[])
456{
457 // ignore source
458 argc--;
459 argv++;
460
461 if (argc < 3) {
462 return "need exactly three arguments: the port name, a key, and a prefix";
463 }
464 std::string target = STR(argv[0]);
465 std::string key = argv[1];
466 std::string prefix = argv[2];
467 NameRecord& nameRecord = getNameRecord(target);
468 return terminate(std::string("port ") + target + " property " + key + " = " + nameRecord.matchProp(key, prefix) + "\n");
469}
470
471std::string NameServer::cmdCheck(int argc, char* argv[])
472{
473 // ignore source
474 argc--;
475 argv++;
476
477 if (argc < 2) {
478 return "need at least two arguments: the port name, and a key";
479 }
480 std::string response;
481 std::string target = STR(argv[0]);
482 std::string key = argv[1];
483 NameRecord& nameRecord = getNameRecord(target);
484 for (int i = 2; i < argc; i++) {
485 std::string val = "false";
486 if (nameRecord.checkProp(key, argv[i])) {
487 val = "true";
488 }
489 if (i > 2) {
490 response += "\n";
491 }
492 response.append("port ").append(target).append(" property ").append(key).append(" value ").append(argv[i]).append(" present ").append(val);
493 }
494 response += "\n";
495 return terminate(response);
496}
497
498
499std::string NameServer::cmdList(int argc, char* argv[])
500{
501 YARP_UNUSED(argc);
502 YARP_UNUSED(argv);
503 std::string response;
504
505 std::multiset<std::string> lines;
506 for (auto& it : nameMap) {
507 NameRecord& rec = it.second;
508 lines.insert(textify(rec.getAddress()));
509 }
510
511 // return result in alphabetical order
512 for (const auto& line : lines) {
513 response += line;
514 }
515
516 return terminate(response);
517}
518
519
520std::string NameServer::cmdBot(int argc, char* argv[])
521{
522 std::string txt;
523 argc--;
524 argv++;
525 if (argc >= 1) {
526 std::string key = argv[0];
527 argc--;
528 argv++;
529 Bottle result = ndispatcher.dispatch(this, key.c_str(), argc, argv);
530 txt = result.toString();
531 }
532 return txt;
533}
534
535
536Bottle NameServer::ncmdList(int argc, char* argv[])
537{
538 Bottle response;
539
540 std::string prefix;
541
542 if (argc == 1) {
543 prefix = STR(argv[0]);
544 }
545
546 response.addString("ports");
547 for (auto& it : nameMap) {
548 NameRecord& rec = it.second;
549 std::string iname = rec.getAddress().getRegName();
550 if (iname.find(prefix) == 0) {
551 if (iname == prefix || iname[prefix.length()] == '/' || prefix[prefix.length() - 1] == '/') {
552 if (rec.getAddress().isValid()) {
553 response.addList() = botify(rec.getAddress());
554 }
555 }
556 }
557 }
558
559 return response;
560}
561
562
563yarp::os::Bottle NameServer::ncmdQuery(int argc, char* argv[])
564{
565 Bottle response;
566 if (argc == 1) {
567 std::string portName = STR(argv[0]);
568 Contact address = queryName(portName);
569 response = botify(address);
570 }
571 return response;
572}
573
574
575yarp::os::Bottle NameServer::ncmdVersion(int argc, char* argv[])
576{
577 YARP_UNUSED(argc);
578 YARP_UNUSED(argv);
579 Bottle response;
580 response.addString("version");
581 response.addString(YARP_VERSION);
582 return response;
583}
584
585
586yarp::os::Bottle NameServer::ncmdSet(int argc, char* argv[])
587{
588
589 Bottle response;
590 if (argc >= 2) {
591 std::string target = STR(argv[0]);
592 std::string key = STR(argv[1]);
593 NameRecord& nameRecord = getNameRecord(target);
594 nameRecord.clearProp(key);
595 for (int i = 2; i < argc; i++) {
596 nameRecord.addProp(key, argv[i]);
597 }
598 response.addString("ok");
599 }
600 return response;
601}
602
603yarp::os::Bottle NameServer::ncmdGet(int argc, char* argv[])
604{
605 Bottle response;
606 if (argc == 2) {
607 std::string target = STR(argv[0]);
608 std::string key = argv[1];
609 NameRecord& nameRecord = getNameRecord(target);
610 return Bottle(nameRecord.getProp(key));
611 }
612 return response;
613}
614
615
616std::string NameServer::cmdGarbageCollect(int argc, char* argv[])
617{
618 YARP_UNUSED(argc);
619 YARP_UNUSED(argv);
620 std::string response;
621
622 response = "No cleaning done.\n";
623
624 return terminate(response);
625}
626
627
628std::string NameServer::textify(const Contact& address)
629{
630 std::string result;
631 if (address.isValid()) {
632 if (address.getPort() >= 0) {
633 result = "registration name ";
634 result = result + address.getRegName() + " ip " + address.getHost() + " port " + yarp::conf::numeric::to_string(address.getPort()) + " type " + address.getCarrier() + "\n";
635 } else {
636 result = "registration name ";
637 result = result + address.getRegName() + " ip " + "none" + " port " + "none" + " type " + address.getCarrier() + "\n";
638 }
639 }
640 return result;
641}
642
643
645{
646 Bottle result;
647 if (address.isValid()) {
649 bname.addString("name");
650 bname.addString(address.getRegName().c_str());
651 Bottle bip;
652 bip.addString("ip");
653 bip.addString(address.getHost().c_str());
654 Bottle bnum;
655 bnum.addString("port_number");
656 bnum.addInt32(address.getPort());
658 bcarrier.addString("carrier");
659 bcarrier.addString(address.getCarrier().c_str());
660
661 result.addString("port");
662 result.addList() = bname;
663 result.addList() = bip;
664 result.addList() = bnum;
665 result.addList() = bcarrier;
666 } else {
668 bstate.addString("error");
669 bstate.addInt32(-2);
670 bstate.addString("port not known");
671 result.addString("port");
672 result.addList() = bstate;
673 }
674 return result;
675}
676
677
678static std::string ns_terminate(const std::string& str)
679{
680 return str + "*** end of message";
681}
682
683std::string NameServer::terminate(const std::string& str)
684{
685 return ns_terminate(str);
686}
687
688
689std::string NameServer::apply(const std::string& txt, const Contact& remote)
690{
691 std::string result = "no command given";
692 mutex.lock();
693 auto ss = yarp::conf::string::split(txt, std::regex{"[\" \t\n]+"});
694 if (ss.size() >= 2) {
695 std::string key = ss.at(1);
696 yCTrace(NAMESERVER, "dispatching to %s", key.c_str());
697 ss.at(1) = remote.getHost();
698
699 // Create argc/argv containing all arguments but the first one
700 std::vector<char*> args;
701 args.reserve(ss.size());
702 std::transform(ss.begin() + 1, ss.end(), std::back_inserter(args), [](const std::string& str) { return const_cast<char*>(str.c_str()); });
703 args.push_back(nullptr);
704 int argc = static_cast<int>(args.size()) - 1;
705 char** argv = args.data();
706
707 result = dispatcher.dispatch(this, key.c_str(), argc, argv);
708 if (result.empty()) {
709 Bottle b = ndispatcher.dispatch(this, key.c_str(), argc, argv);
710 result = b.toString();
711 if (!result.empty()) {
712 result = result + "\n";
713 result = terminate(result);
714 }
715 }
716 yCTrace(NAMESERVER, "name server request -- %s", txt.c_str());
717 yCTrace(NAMESERVER, "name server result -- %s", result.c_str());
718 }
719 mutex.unlock();
720 return result;
721}
722
723
724bool NameServer::apply(const Bottle& cmd, Bottle& result, const Contact& remote)
725{
726 Bottle rcmd;
727 rcmd.addString("ignored_legacy");
728 rcmd.append(cmd);
729 std::string in = rcmd.toString();
730 std::string out = apply(in, remote);
731 result.fromString(out);
732 return true;
733}
734
735
736#ifndef DOXYGEN_SHOULD_SKIP_THIS
737
739 public PortReader
740{
741private:
743
744public:
746 {
747 this->server = server;
748 }
749
750 bool read(ConnectionReader& reader) override
751 {
752 yCTrace(NAMESERVER, "read start");
753 std::string ref = "NAME_SERVER ";
754 bool ok = true;
755 std::string msg = "?";
756 bool haveMessage = false;
757 if (ok) {
758 if (reader.isTextMode()) {
759 msg = reader.expectText();
760 } else {
761 // migrate to binary mode support, eventually optimize
762 Bottle b;
763 b.read(reader);
764 msg = b.toString();
765 }
766 haveMessage = (!msg.empty());
767 msg = ref + msg;
768 }
769 if (reader.isActive() && haveMessage) {
770 yCDebug(NAMESERVER, "name server got message %s", msg.c_str());
771 size_t index = msg.find("NAME_SERVER");
772 if (index == 0) {
773 Contact remote = reader.getRemoteContact();
774 yCDebug(NAMESERVER, "name server receiving from %s", remote.toURI().c_str());
775 yCDebug(NAMESERVER, "name server request is %s", msg.c_str());
776 std::string result = server->apply(msg, remote);
777 ConnectionWriter* os = reader.getWriter();
778 if (os != nullptr) {
779 if (result.empty()) {
780 result = ns_terminate(std::string("unknown command ") + msg + "\n");
781 }
782 // This change is just to make Microsoft Telnet happy
783 std::string tmp;
784 for (char i : result) {
785 if (i == '\n') {
786 tmp += '\r';
787 }
788 tmp += i;
789 }
790 tmp += '\r';
791 os->appendText(tmp);
792
793 yCDebug(NAMESERVER, "name server reply is %s", result.c_str());
794 std::string resultSparse = result;
795 size_t end = resultSparse.find("\n*** end of message");
796 if (end != std::string::npos) {
797 resultSparse[end] = '\0';
798 }
799 yCInfo(NAMESERVER, "%s", resultSparse.c_str());
800 }
801 } else {
802 yCInfo(NAMESERVER, "Name server ignoring unknown command: %s", msg.c_str());
803 }
804 }
805 yCTrace(NAMESERVER, "read stop");
806 return true;
807 }
808};
809
810
811class MainNameServer :
812 public NameServer,
813 public PortReaderCreator
814{
815private:
816 Port* port;
817
818public:
819 MainNameServer(int basePort, Port* port = nullptr) :
820 port(port)
821 {
822 setBasePort(basePort);
823 }
824
825 void setPort(Port& port)
826 {
827 this->port = &port;
828 }
829
830 void onEvent(Bottle& event) override
831 {
832 if (port != nullptr) {
833 port->write(event);
834 }
835 }
836
837 PortReader* create() const override
838 {
839 return new MainNameServerWorker(const_cast<MainNameServer*>(this));
840 }
841};
842
843
844#endif // DOXYGEN_SHOULD_SKIP_THIS
#define STR(x)
const yarp::os::LogComponent & NAMESERVER()
static std::string STR_HELP(const char *txt)
static std::string ns_terminate(const std::string &str)
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
void addVocab32(yarp::conf::vocab32_t x)
Places a vocabulary item in the bottle, at the end of the list.
Definition Bottle.cpp:164
void fromString(const std::string &text)
Initializes bottle from a string.
Definition Bottle.cpp:204
Bottle & addList()
Places an empty nested list in the bottle, at the end of the list.
Definition Bottle.cpp:182
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Definition Bottle.cpp:240
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition Bottle.cpp:170
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition Bottle.cpp:211
A mini-server for performing network communication in the background.
An interface for reading from a network connection.
virtual bool isTextMode() const =0
Check if the connection is text mode.
virtual ConnectionWriter * getWriter()=0
Gets a way to reply to the message, if possible.
virtual std::string expectText(const char terminatingChar='\n')=0
Read some text from the network connection.
virtual Contact getRemoteContact() const =0
Gets information about who is supplying the data being read, if that information is available.
virtual bool isActive() const =0
An interface for writing to a network connection.
virtual void appendText(const std::string &str, const char terminate='\n')=0
Send a terminated string to the network connection.
Represents how to reach a part of a YARP network.
Definition Contact.h:33
bool isValid() const
Checks if a Contact is tagged as valid.
Definition Contact.cpp:298
std::string getRegName() const
Get the name associated with this Contact.
Definition Contact.cpp:217
std::string toString() const
Get a textual representation of the Contact.
Definition Contact.cpp:303
std::string toURI(bool includeCarrier=true) const
Get a representation of the Contact as a URI.
Definition Contact.cpp:313
int getPort() const
Get the port number associated with this Contact for socket communication.
Definition Contact.cpp:239
std::string getCarrier() const
Get the carrier associated with this Contact for socket communication.
Definition Contact.cpp:250
std::string getHost() const
Get the host name associated with this Contact for socket communication.
Definition Contact.cpp:228
static int getDefaultPortRange()
Under normal operation, YARP has a name server that manages a pool of (socket) ports starting at a po...
Definition Network.cpp:1961
A creator for readers.
Interface implemented by all objects that can read themselves from the network, such as Bottle object...
Definition PortReader.h:24
A mini-server for network communication.
Definition Port.h:46
bool write(const PortWriter &writer, const PortWriter *callback=nullptr) const override
Write an object to the port.
Definition Port.cpp:436
A single value (typically within a Bottle).
Definition Value.h:43
void fromString(const char *str)
Set value to correspond to a textual representation.
Definition Value.cpp:351
virtual std::string asString() const
Get string value.
Definition Value.cpp:234
Implementation of a YARP2-conforming name server.
Definition NameServer.h:43
static std::string textify(const Contact &address)
std::string apply(const std::string &txt, const Contact &remote) override
Contact queryName(const std::string &name)
static yarp::os::Bottle botify(const Contact &address)
Contact unregisterName(const std::string &name)
std::string terminate(const std::string &str)
virtual void onEvent(yarp::os::Bottle &event)
Definition NameServer.h:83
Contact registerName(const std::string &name, const Contact &address)
Definition NameServer.h:55
#define yCInfo(component,...)
#define yCError(component,...)
#define yCAssert(component, x)
#define yCTrace(component,...)
#define yCDebug(component,...)
#define YARP_OS_LOG_COMPONENT(name, name_string)
STL namespace.
std::string to_string(IntegerType x)
Definition numeric.h:115
ContainerT split(const typename ContainerT::value_type &s, std::basic_regex< typename ContainerT::value_type::value_type > regex)
Utility to split a string by a separator, into a vector of strings.
Definition string.h:26
The components from which ports and connections are built.
An interface to the operating system, including Port based communication.
#define YARP_VERSION
Definition version.h:14
#define YARP_UNUSED(var)
Definition api.h:162