Logo ROOT   6.07/09
Reference Guide
hclientbonj.C
Go to the documentation of this file.
1 /// \file
2 /// \ingroup tutorial_net
3 /// Client program which creates and fills a histogram. Every 1000 fills
4 /// the histogram is send to the server which displays the histogram.
5 ///
6 /// To run this demo do the following:
7 /// - Open three windows
8 /// - Start ROOT in all three windows
9 /// - Execute in the first window: .x hserv.C (or hserv2.C)
10 /// - Execute in the second and third windows: .x hclient.C
11 /// If you want to run the hserv.C on a different host, just change
12 /// "localhost" in the TSocket ctor below to the desired hostname.
13 ///
14 /// The script argument "evol" can be used when using a modified version
15 /// of the script where the clients and server are on systems with
16 /// different versions of ROOT. When evol is set to kTRUE the socket will
17 /// support automatic schema evolution between the client and the server.
18 ///
19 /// \macro_code
20 ///
21 /// \author Fons Rademakers
22 
23 #include "TBenchmark.h"
24 #include "TList.h"
25 #include "TInetAddress.h"
26 #include "TSocket.h"
27 #include "TMessage.h"
28 #include "TH1.h"
29 #include "TH2.h"
30 #include "TRandom.h"
31 #include "TBonjourBrowser.h"
32 #include "TBonjourResolver.h"
33 #include "TBonjourRecord.h"
34 
35 
36 static Bool_t gEvo = kFALSE;
37 
38 void ConnectToServer(const TInetAddress *hostb, Int_t port)
39 {
40  // Called by the Bonjour resolver with the host and port to which
41  // we can connect.
42 
43  // Connect only once...
45  TInetAddress host = *hostb;
46  delete resolver;
47 
48  printf("ConnectToServer: host = %s, port = %d\n", host.GetHostName(), port);
49 
50  //--- Here starts original hclient.C code ---
51 
52  // Open connection to server
53  TSocket *sock = new TSocket(host.GetHostName(), port);
54 
55  // Wait till we get the start message
56  char str[32];
57  sock->Recv(str, 32);
58 
59  // server tells us who we are
60  int idx = !strcmp(str, "go 0") ? 0 : 1;
61 
62  Float_t messlen = 0;
63  Float_t cmesslen = 0;
64  if (idx == 1)
65  sock->SetCompressionLevel(1);
66 
67  TH1 *hpx;
68  if (idx == 0) {
69  // Create the histogram
70  hpx = new TH1F("hpx","This is the px distribution",100,-4,4);
71  hpx->SetFillColor(48); // set nice fill-color
72  } else {
73  hpx = new TH2F("hpxpy","py vs px",40,-4,4,40,-4,4);
74  }
75 
77  TMessage mess(kMESS_OBJECT);
78  //TMessage mess(kMESS_OBJECT | kMESS_ACK);
79 
80  // Fill histogram randomly
81  gRandom->SetSeed();
82  Float_t px, py;
83  const int kUPDATE = 1000;
84  for (int i = 0; i < 25000; i++) {
85  gRandom->Rannor(px,py);
86  if (idx == 0)
87  hpx->Fill(px);
88  else
89  hpx->Fill(px,py);
90  if (i && (i%kUPDATE) == 0) {
91  mess.Reset(); // re-use TMessage object
92  mess.WriteObject(hpx); // write object in message buffer
93  sock->Send(mess); // send message
94  messlen += mess.Length();
95  cmesslen += mess.CompLength();
96  }
97  }
98  sock->Send("Finished"); // tell server we are finished
99 
100  if (cmesslen > 0)
101  printf("Average compression ratio: %g\n", messlen/cmesslen);
102 
103  gBenchmark->Show("hclient");
104 
105  // Close the socket
106  sock->Close();
107 }
108 
109 void UpdateBonjourRecords(TList *records)
110 {
111  // Browse for Bonjour record of type "_hserv2._tcp." in domain "local.".
112  // When found, create Bonjour resolver to get host and port of this record.
113 
114  static Bool_t resolved = kFALSE;
115 
116  // we can be called multiple times whenever a new server appears
117  printf("UpdateBonjourRecords (resolved = %s)\n", resolved ? "kTRUE" : "kFALSE");
118 
119  if (resolved) return;
120 
121  // Look for _hserv2._tcp. in local. domain and try to resolve it
122  TBonjourRecord *rec;
123  TIter next(records);
124  while ((rec = (TBonjourRecord*) next())) {
125  if (!strcmp(rec->GetRegisteredType(), "_hserv2._tcp.") &&
126  !strcmp(rec->GetReplyDomain(), "local.")) {
127  rec->Print();
128  TBonjourResolver *resolver = new TBonjourResolver;
129  resolver->Connect("RecordResolved(TInetAddress*,Int_t)", 0, 0,
130  "ConnectToServer(TInetAddress*,Int_t)");
131  resolver->ResolveBonjourRecord(*rec);
132  resolved = kTRUE;
133  }
134  }
135 }
136 
137 void hclientbonj(Bool_t evol=kFALSE)
138 {
139  gEvo = evol;
140 
141  gBenchmark->Start("hclient");
142 
143  TBonjourBrowser *browser = new TBonjourBrowser;
144  browser->Connect("CurrentBonjourRecordsChanged(TList*)", 0, 0,
145  "UpdateBonjourRecords(TList*)");
146  browser->BrowseForServiceType("_hserv2._tcp");
147 }
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3127
virtual void Rannor(Float_t &a, Float_t &b)
Return 2 numbers distributed following a gaussian with mean=0 and sigma=1.
Definition: TRandom.cxx:460
const char * GetHostName() const
Definition: TInetAddress.h:75
float Float_t
Definition: RtypesCore.h:53
Int_t ResolveBonjourRecord(const TBonjourRecord &record)
Resolve Bonjour service to IP address and port.
R__EXTERN void * gTQSender
Definition: TQObject.h:49
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:818
THist< 1, float, THistStatContent, THistStatUncertainty > TH1F
Definition: THist.hxx:302
This class represents an Internet Protocol (IP) address.
Definition: TInetAddress.h:40
virtual void Show(const char *name)
Stops Benchmark name and Prints results.
Definition: TBenchmark.cxx:157
void Print(Option_t *opt="") const
Print TBonjourRecord.
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual void Start(const char *name)
Starts Benchmark with the specified name.
Definition: TBenchmark.cxx:174
virtual void SetSeed(ULong_t seed=0)
Set the random generator seed.
Definition: TRandom.cxx:568
A doubly linked list.
Definition: TList.h:47
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot...
Definition: TQObject.cxx:1137
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:42
R__EXTERN TBenchmark * gBenchmark
Definition: TBenchmark.h:63
const char * GetReplyDomain() const
static void EnableSchemaEvolutionForAll(Bool_t enable=kTRUE)
Static function enabling or disabling the automatic schema evolution.
Definition: TMessage.cxx:116
R__EXTERN TRandom * gRandom
Definition: TRandom.h:66
const char * GetRegisteredType() const
The TH1 histogram class.
Definition: TH1.h:80
Int_t BrowseForServiceType(const char *serviceType)
Tell Bonjour to start browsing for a specific type of service.
const Bool_t kTRUE
Definition: Rtypes.h:91
THist< 2, float, THistStatContent, THistStatUncertainty > TH2F
Definition: THist.hxx:308