Jpp 19.3.0-rc.1
the software that should make you happy
Loading...
Searching...
No Matches
JControlHost.hh
Go to the documentation of this file.
1#ifndef __JNET__JCONTROLHOST__
2#define __JNET__JCONTROLHOST__
3
4#include <string>
5#include <sstream>
6#include <arpa/inet.h>
7#include <set>
8
9#include "JNet/JPrefix.hh"
10#include "JNet/JTCPSocket.hh"
12#include "JNet/JHostname.hh"
13#include "JLang/JException.hh"
14#include "JLang/JThrow.hh"
15#include "JLang/JTimeval.hh"
16#include "JMath/JMath.hh"
17
18
19/**
20 * \author mdejong
21 */
22
23namespace JNET {}
24namespace JPP { using namespace JNET; }
25
26namespace JNET {
27
28 using JMATH::JMath;
30 using JLANG::JThrow;
31 using JLANG::JTimeval;
32
33
34 static const std::string CHOO_VERSION = "1.0";
35
36
37 /**
38 * ControlHost subscription types.
39 */
42 SUBSCRIBE_ANY = 'w'
43 //SUBSCRIBE_SHARED_MEMORY = 'm'
44 };
45
46
47 /**
48 * ControlHost subscription.
49 */
51 public JTag
52 {
53 public:
54 /**
55 * Constructor.
56 *
57 * \param sub subscription
58 * \param tag tag
59 */
61 const JTag& tag) :
62 JTag (tag),
63 subscription(sub)
64 {}
65
66
67 /**
68 * Get subscription type.
69 *
70 * \return subscription
71 */
73 {
74 return subscription;
75 }
76
77
78 /**
79 * Convert subscription to string.
80 *
81 * \return subscription
82 */
83 std::string toString() const
84 {
85 return std::string(1, (char) subscription) + " " + JTag::toString();
86 }
87
88
89 protected:
91 };
92
93
94 /**
95 * Auxiliary class for all subscription.
96 */
98 public JSubscription
99 {
100 /**
101 * Constructor.
102 *
103 * \param tag tag
104 */
105 JSubscriptionAll(const JTag& tag) :
107 {}
108 };
109
110
111 /**
112 * Auxiliary class for any subscription.
113 */
115 public JSubscription
116 {
117 /**
118 * Constructor.
119 *
120 * \param tag tag
121 */
122 JSubscriptionAny(const JTag& tag) :
124 {}
125 };
126
127
128 /**
129 * Subscription list.
130 */
132 protected std::set<JSubscription> ,
133 public JMath<JSubscriptionList>
134 {
135 public:
136
139
140
141 /**
142 * Default constructor.
143 */
146
147
148 /**
149 * Copy constructor.
150 *
151 * \param subscription subscription
152 */
153 JSubscriptionList(const JSubscription& subscription)
154 {
155 add(subscription);
156 }
157
158
159 /**
160 * Smart pointer.
161 *
162 * \return pointer to set
163 */
165 {
166 return static_cast<const std::set<JSubscription>*>(this);
167 }
168
169
170 /**
171 * Add subscription.
172 *
173 * \param subscription subscription
174 */
175 JSubscriptionList& add(const JSubscription& subscription)
176 {
177 const_iterator p = this->find(subscription);
178
179 if (p != this->end() && p->getID() == subscription.getID()) {
180
181 if (p-> getSubscription() == SUBSCRIBE_ALL ||
182 subscription.getSubscription() == SUBSCRIBE_ANY)
183 return *this; // maintain higher subscription level
184 else
185 this->erase(p); // remove lower subscription level
186 }
187
188 this->insert(subscription);
189
190 return *this;
191 }
192
193
194 /**
195 * Add subscription.
196 *
197 * \param subscription subscription
198 * \return this subscription
199 */
201 {
202 for (JSubscriptionList::const_iterator i = subscription.begin(); i != subscription.end(); ++i) {
203 this->add(*i);
204 }
205
206 return *this;
207 }
208
209
210 /**
211 * Convert subscription list to string.
212 *
213 * \return subscription
214 */
215 std::string toString() const
216 {
217 std::string buffer;
218
219 for (const_iterator i = this->begin(); i != this->end(); ++i)
220 buffer += ' ' + i->toString();
221
222 return buffer;
223 }
224 };
225
226
227 /**
228 * Add operator.
229 *
230 * \param first subscription
231 * \param second subscription
232 * \return subscription list
233 */
234 inline JSubscriptionList operator+(const JSubscription& first, const JSubscription& second)
235 {
236 JSubscriptionList buffer;
237
238 buffer.add(first);
239 buffer.add(second);
240
241 return buffer;
242 }
243
244
245 /**
246 * ControlHost class.
247 */
249 public JSocketBlocking,
250 public JThrow<JControlHost>
251 {
252 protected:
253 /**
254 * Default constructor.
255 */
257 {
258 configure();
259 }
260
261
262 public:
263 /**
264 * Check special ControlHost tags.
265 *
266 * \param tag tag
267 * \return true if possibly special tag; else false
268 */
269 static bool maybe_special(const JTag& tag)
270 {
271 return tag[0] == '_';
272 }
273
274
275 /**
276 * Check validity of subscription specifier.
277 *
278 * \param c subscription specifier
279 * \return true if valid; else false
280 */
281 static bool is_valid(const char c)
282 {
283 return (c == SUBSCRIBE_ALL ||
284 c == SUBSCRIBE_ANY);// ||
285 //c == SUBSCRIBE_SHARED_MEMORY);
286 }
287
288
289 /**
290 * Constructor.
291 *
292 * \param server host name and optional port number
293 */
294 JControlHost(const JHostname& server)
295 {
296 if (server.hostname != "")
297 connect(server.hostname, server.port);
298 else
299 connect(server.port);
300
301 configure();
302 }
303
304
305 /**
306 * Constructor.
307 *
308 * \param server host name
309 * \param port port
310 */
311 JControlHost(const std::string& server,
312 const int port)
313 {
314 connect(server, port);
315
316 configure();
317 }
318
319
320 /**
321 * Constructor.
322 *
323 * \param ip_number IP number
324 * \param port port
325 */
326 JControlHost(const int ip_number,
327 const int port = DISPATCH_PORT)
328 {
329 connect(ip_number, port);
330
331 configure();
332 }
333
334
335 /**
336 * Constructor.
337 *
338 * \param socket socket
339 */
340 JControlHost(const JTCPSocket& socket) :
341 JSocketBlocking(socket)
342 {}
343
344
345 /**
346 * Destructor.
347 */
349 {
350 shutdown();
351 }
352
353
354 /**
355 * Subscribe to single tag.
356 *
357 * \param subscription subscription
358 * \return 0 if OK; -1 if socket error
359 */
360 int Subscribe(const JSubscription& subscription)
361 {
362 return PutFullString(DISPTAG_Subscribe, subscription.toString());
363 }
364
365
366 /**
367 * Subscribe to list of tags.
368 *
369 * \param subscription subscription
370 * \return 0 if OK; -1 if socket error
371 */
372 int Subscribe(const JSubscriptionList& subscription)
373 {
374 return PutFullString(DISPTAG_Subscribe, subscription.toString());
375 }
376
377
378 /**
379 * Identify.
380 *
381 * \param nick_name nick name
382 * \return 0 if OK; -1 if socket error
383 */
384 int MyId(const std::string& nick_name)
385 {
386 return PutFullString(DISPTAG_MyId, nick_name);
387 }
388
389
390 /**
391 * Tell server to send next message.
392 *
393 * \return 0 if OK; -1 if socket error
394 */
396 {
397 return PutFullData(DISPTAG_Gime, NULL, 0);
398 }
399
400
401 /**
402 * Tell server to send messages forever.
403 *
404 * \return 0 if OK; -1 if socket error
405 */
407 {
408 return PutFullData(DISPTAG_Always, NULL, 0);
409 }
410
411
412 /**
413 * Send data.
414 *
415 * \param tag tag
416 * \param buffer data
417 * \param length number of bytes
418 * \return 0 if OK; -1 if socket error; -2 if other error
419 */
420 int PutFullData(const JTag& tag, const void* buffer, const long long int length)
421 {
422 try {
423
424 JPrefix __prefix__(tag, length);
425
426 write((char*) &__prefix__, sizeof(JPrefix));
427
428 if (length != 0) {
429 write((char*) buffer, (int) length);
430 }
431
432 return 0;
433 }
434 catch (const JSocketException& error) {
435 return Throw(error, -1);
436 }
437 }
438
439
440 /**
441 * Send data.
442 *
443 * \param tag tag
444 * \param buffer data
445 * \param length number of bytes
446 * \return 0 if OK; -1 if socket error; -2 if other error
447 */
448 int PutFullData(const std::string& tag, const void* buffer, const long long int length)
449 {
450 try {
451 return PutFullData(JTag(tag), buffer, length);
452 }
453 catch (const JSocketException& error) {
454 return Throw(error, -1);
455 }
456 catch (const JControlHostException& error) {
457 return Throw(error, -2);
458 }
459 }
460
461
462 /**
463 * Send string.
464 *
465 * \param tag tag
466 * \param buffer data
467 * \return 0 if OK; -1 if socket error; -2 if other error
468 */
469 int PutFullString(const JTag& tag,
470 const std::string& buffer)
471 {
472 return PutFullData(tag, buffer.c_str(), buffer.size());
473 }
474
475
476 /**
477 * Send string.
478 *
479 * \param tag tag
480 * \param buffer data
481 * \return 0 if OK; -1 if socket error; -2 if other error
482 */
483 int PutFullString(const std::string& tag,
484 const std::string& buffer)
485 {
486 return PutFullData(tag, buffer.c_str(), buffer.size());
487 }
488
489
490 /**
491 * Send version.
492 *
493 * \return 0 if OK; -1 if socket error; -2 if other error
494 */
496 {
498 }
499
500
501 /**
502 * Wait for header.
503 *
504 * \param prefix prefix
505 * \return 0 if OK; -1 if socket error
506 */
508 {
509 try {
510
511 read((char*) &this->prefix, sizeof(JPrefix));
512
513 prefix = this->prefix;
514
515 return 0;
516 }
517 catch (const JSocketException& error) {
518 return Throw(error, -1);
519 }
520 }
521
522
523 /**
524 * Wait for header.
525 *
526 * \param tag tag
527 * \param length number of bytes
528 * \return 0 if OK; -1 if socket error
529 */
530 int WaitHead(std::string& tag, long long int& length)
531 {
532 const int rvalue = WaitHead(this->prefix);
533
534 if (rvalue == 0) {
535 tag = this->prefix.getTag();
536 length = this->prefix.getSize();
537 }
538
539 return rvalue;
540 }
541
542
543 /**
544 * Check for header, without waiting.
545 *
546 * \param prefix prefix
547 * \param timeout timeout
548 * \return 1 if header; 0 if no header; -1 if socket error
549 */
551 {
552 try {
553
554 if (in_avail(timeout)) {
555
557
558 return 1;
559
560 } else {
561
562 return 0;
563 }
564 }
565 catch (const JSocketException& error) {
566 return Throw(error, -1);
567 }
568 }
569
570
571 /**
572 * Check for header, without waiting.
573 *
574 * \param tag tag
575 * \param length number of bytes
576 * \param timeout_us timeout [us]
577 * \return 1 if header; 0 if no header; -1 if socket error
578 */
579 int CheckHead(std::string& tag, long long int& length, const int timeout_us = 0)
580 {
581 const int rvalue = CheckHead(this->prefix, timeout_us);
582
583 if (rvalue == 1) {
584 tag = this->prefix.getTag();
585 length = this->prefix.getSize();
586 }
587
588 return rvalue;
589 }
590
591
592 /**
593 * Receive data.
594 *
595 * \param buffer data
596 * \param length number of bytes
597 * \return 0 if OK; -1 if socket error
598 */
599 int GetFullData(void* buffer, long long int length)
600 {
601 try {
602
603 read((char*) buffer, (int) length);
604
605 return 0;
606 }
607 catch (const JSocketException& error) {
608 return Throw(error, -1);
609 }
610 }
611
612
613 /**
614 * Receive string.
615 *
616 * \param buffer data
617 * \return 0 if OK; -1 if socket error
618 */
619 int GetFullString(std::string& buffer)
620 {
621 buffer.resize(this->prefix.getSize());
622
623 return GetFullData((char*) buffer.data(), buffer.size());
624 }
625
626
627 /**
628 * Locate ControlHost client(s).
629 *
630 * \param host_name host name
631 * \param nick_name nick name
632 * \param answer list of host names
633 * \return 0 if OK; -1 if socket error
634 */
635 static int WhereIs(const std::string& host_name,
636 const std::string& nick_name,
637 std::string& answer)
638 {
639 try {
640
641 using namespace std;
642
643 JControlHost socket(host_name);
644
645 socket.PutFullString(DISPTAG_WhereIs, nick_name);
646
647 string tag;
648 long long int length;
649
650 socket.WaitHead(tag, length);
651 socket.GetFullString(answer);
652
653 return 0;
654 }
655 catch (const JSocketException& error) {
656 return Throw(error, -1);
657 }
658 }
659
660
661 /**
662 * Configure socket (factory reset).
663 *
664 * \return 0 if OK; -1 if socket error
665 */
667 {
668 try {
669
670 setTcpNoDelay (true);
671 setReuseAddress(true);
672 setKeepAlive (true);
673 setSendBufferSize (128*1024);
674 setReceiveBufferSize(128*1024);
675 setNonBlocking (false);
676
677 return 0;
678 }
679 catch (const JSocketException& error) {
680 return Throw(error, -1);
681 }
682 }
683
684
685 private:
687
692 };
693
694
695 /**
696 * Match name.
697 */
699}
700
701#endif
Exceptions.
Base class for data structures with artithmetic capabilities.
Exception handling.
Exception for ControlHost.
bool in_avail(JTimeval timeout=JTimeval::min()) const
Check availability of input.
Definition JFile.hh:106
Exception for socket.
Auxiliary base class for controling the throwing of exceptions.
Definition JThrow.hh:25
static void Throw(const bool option)
Definition JThrow.hh:37
Auxiliary class for time values.
Definition JTimeval.hh:29
static JTimeval min()
Get minimal time value.
Definition JTimeval.hh:119
ControlHost class.
int MyId(const std::string &nick_name)
Identify.
JControlHost(const std::string &server, const int port)
Constructor.
int PutFullString(const JTag &tag, const std::string &buffer)
Send string.
static int WhereIs(const std::string &host_name, const std::string &nick_name, std::string &answer)
Locate ControlHost client(s).
int GetFullString(std::string &buffer)
Receive string.
JControlHost(const JHostname &server)
Constructor.
int WaitHead(std::string &tag, long long int &length)
Wait for header.
JControlHost(JControlHost &&)
int WaitHead(JPrefix &prefix)
Wait for header.
int CheckHead(JPrefix &prefix, JTimeval timeout=JTimeval::min())
Check for header, without waiting.
JControlHost()
Default constructor.
int configure()
Configure socket (factory reset).
int GetFullData(void *buffer, long long int length)
Receive data.
JControlHost & operator=(const JControlHost &)
int SendMeAlways()
Tell server to send messages forever.
static bool maybe_special(const JTag &tag)
Check special ControlHost tags.
int Subscribe(const JSubscriptionList &subscription)
Subscribe to list of tags.
int PutFullData(const std::string &tag, const void *buffer, const long long int length)
Send data.
JControlHost(const JControlHost &)
JControlHost(const JTCPSocket &socket)
Constructor.
static bool is_valid(const char c)
Check validity of subscription specifier.
int SendMeNext()
Tell server to send next message.
~JControlHost()
Destructor.
int PutFullData(const JTag &tag, const void *buffer, const long long int length)
Send data.
int PutFullString(const std::string &tag, const std::string &buffer)
Send string.
JControlHost & operator=(JControlHost &&)
JControlHost(const int ip_number, const int port=DISPATCH_PORT)
Constructor.
int CheckHead(std::string &tag, long long int &length, const int timeout_us=0)
Check for header, without waiting.
int Subscribe(const JSubscription &subscription)
Subscribe to single tag.
int Connected()
Send version.
ControlHost prefix.
Definition JPrefix.hh:33
int getSize() const
Get size.
Definition JPrefix.hh:62
Blocking socket I/O.
int read(char *buffer, const int length) override
Read data from socket.
int write(const char *buffer, const int length) override
Write data to socket.
void setReceiveBufferSize(const int size)
Set receive buffer size.
Definition JSocket.hh:148
int shutdown()
Shut down socket.
Definition JSocket.hh:89
void setReuseAddress(const bool on)
Set reuse address.
Definition JSocket.hh:126
void setKeepAlive(const bool on)
Set keep alive of socket.
Definition JSocket.hh:104
void setSendBufferSize(const int size)
Set send buffer size.
Definition JSocket.hh:170
Subscription list.
JSubscriptionList & add(const JSubscriptionList &subscription)
Add subscription.
std::string toString() const
Convert subscription list to string.
std::set< JSubscription >::const_iterator const_iterator
JSubscriptionList(const JSubscription &subscription)
Copy constructor.
JSubscriptionList & add(const JSubscription &subscription)
Add subscription.
JSubscriptionList()
Default constructor.
std::set< JSubscription >::const_reverse_iterator const_reverse_iterator
const std::set< JSubscription > * operator->() const
Smart pointer.
ControlHost subscription.
JSubscription_t subscription
JSubscription_t getSubscription() const
Get subscription type.
std::string toString() const
Convert subscription to string.
JSubscription(const JSubscription_t sub, const JTag &tag)
Constructor.
TCP socket.
Definition JTCPSocket.hh:30
void connect(const int port)
Connect to port on local host.
void setNonBlocking(const bool on)
Set non-blocking of I/O.
Definition JTCPSocket.hh:56
void setTcpNoDelay(const bool on)
Set TCP no-delay.
ControlHost tag.
Definition JTag.hh:38
std::string toString() const
Convert tag to string.
Definition JTag.hh:171
const JTag & getTag() const
Get tag.
Definition JTag.hh:86
JTag_t getID() const
Get identifier.
Definition JTag.hh:160
static const JTag DISPTAG_Always("_Always")
JSubscriptionList operator+(const JSubscription &first, const JSubscription &second)
Add operator.
static const JTag DISPTAG_Gime("_Gime")
JSubscription_t
ControlHost subscription types.
@ SUBSCRIBE_ANY
@ SUBSCRIBE_ALL
static const JTag DISPTAG_Version("_Version")
static const int DISPATCH_PORT
Default ControlHost port.
Definition JHostname.hh:27
static const JTag DISPTAG_WhereIs("_WhereIs")
static const JTag DISPTAG_MyId("_MyId")
static const JTag DISPTAG_Subscribe("_Subscri")
Special ControlHost tags.
JControlHost ControlHost
Match name.
static const std::string CHOO_VERSION
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary base class for aritmetic operations of derived class types.
Definition JMath.hh:347
Auxiliary data structure for hostname and port number.
Definition JHostname.hh:35
std::string hostname
Definition JHostname.hh:171
Auxiliary class for all subscription.
JSubscriptionAll(const JTag &tag)
Constructor.
Auxiliary class for any subscription.
JSubscriptionAny(const JTag &tag)
Constructor.