Logo ROOT   6.16/01
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
36static Bool_t gEvo = kFALSE;
37
38void 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
78 //TMessage mess(kMESS_OBJECT | kMESS_ACK);
79
80 // Fill histogram randomly
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
109void 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
137void 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}
@ kMESS_OBJECT
Definition: MessageTypes.h:35
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
R__EXTERN TBenchmark * gBenchmark
Definition: TBenchmark.h:59
R__EXTERN void * gTQSender
Definition: TQObject.h:45
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void Start(const char *name)
Starts Benchmark with the specified name.
Definition: TBenchmark.cxx:174
virtual void Show(const char *name)
Stops Benchmark name and Prints results.
Definition: TBenchmark.cxx:157
Int_t BrowseForServiceType(const char *serviceType)
Tell Bonjour to start browsing for a specific type of service.
const char * GetReplyDomain() const
void Print(Option_t *opt="") const
Print TBonjourRecord.
const char * GetRegisteredType() const
Int_t ResolveBonjourRecord(const TBonjourRecord &record)
Resolve Bonjour service to IP address and port.
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:571
The TH1 histogram class.
Definition: TH1.h:56
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3251
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:250
This class represents an Internet Protocol (IP) address.
Definition: TInetAddress.h:36
const char * GetHostName() const
Definition: TInetAddress.h:71
A doubly linked list.
Definition: TList.h:44
static void EnableSchemaEvolutionForAll(Bool_t enable=kTRUE)
Static function enabling or disabling the automatic schema evolution.
Definition: TMessage.cxx:116
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:867
virtual void SetSeed(ULong_t seed=0)
Set the random generator seed.
Definition: TRandom.cxx:589
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:481
void SetCompressionLevel(Int_t level=ROOT::RCompressionSetting::ELevel::kUseMin)
See comments for function SetCompressionSettings.
Definition: TSocket.cxx:1059
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:817
virtual void Close(Option_t *opt="")
Close the socket.
Definition: TSocket.cxx:389
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition: TSocket.cxx:522