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