Logo ROOT   6.10/09
Reference Guide
spyserv.C
Go to the documentation of this file.
1 /// \file
2 /// \ingroup tutorial_net
3 /// Server program which allows clients, "spies", to connect and snoop objects.
4 /// To run this demo do the following:
5 /// - open two or more windows
6 /// - start root in all windows
7 /// - execute in the first window: .x spyserv.C (or spyserv.C++)
8 /// - execute in the other window(s): .x spy.C (or spy.C++)
9 /// - in the "spy" client windows click the "Connect" button and snoop
10 /// the histograms by clicking on the "hpx", "hpxpy" and "hprof"
11 /// buttons
12 /// \macro_code
13 ///
14 /// \author Fons Rademakers
15 
16 #include "TH1.h"
17 #include "TH2.h"
18 #include "TProfile.h"
19 #include "TCanvas.h"
20 #include "TFrame.h"
21 #include "TSocket.h"
22 #include "TServerSocket.h"
23 #include "TMonitor.h"
24 #include "TMessage.h"
25 #include "TRandom.h"
26 #include "TList.h"
27 #include "TError.h"
28 
29 
30 class SpyServ {
31 private:
32  TCanvas *fCanvas; // main canvas
33  TH1F *fHpx; // 1-D histogram
34  TH2F *fHpxpy; // 2-D histogram
35  TProfile *fHprof; // profile histogram
36  TServerSocket *fServ; // server socket
37  TMonitor *fMon; // socket monitor
38  TList *fSockets; // list of open spy sockets
39 public:
40  SpyServ();
41  ~SpyServ();
42 
43  void HandleSocket(TSocket *s);
44 };
45 
46 
47 void SpyServ::HandleSocket(TSocket *s)
48 {
49  if (s->IsA() == TServerSocket::Class()) {
50  // accept new connection from spy
51  TSocket *sock = ((TServerSocket*)s)->Accept();
52  fMon->Add(sock);
53  fSockets->Add(sock);
54  printf("accepted connection from %s\n", sock->GetInetAddress().GetHostName());
55  } else {
56  // we only get string based requests from the spy
57  char request[64];
58  if (s->Recv(request, sizeof(request)) <= 0) {
59  fMon->Remove(s);
60  fSockets->Remove(s);
61  printf("closed connection from %s\n", s->GetInetAddress().GetHostName());
62  delete s;
63  return;
64  }
65 
66  // send requested object back
67  TMessage answer(kMESS_OBJECT);
68  if (!strcmp(request, "get hpx"))
69  answer.WriteObject(fHpx);
70  else if (!strcmp(request, "get hpxpy"))
71  answer.WriteObject(fHpxpy);
72  else if (!strcmp(request, "get hprof"))
73  answer.WriteObject(fHprof);
74  else
75  Error("SpyServ::HandleSocket", "unexpected message");
76  s->Send(answer);
77  }
78 }
79 
80 SpyServ::SpyServ()
81 {
82  // Create the server process to fills a number of histograms.
83  // A spy process can connect to it and ask for the histograms.
84  // There is no apriori limit for the number of concurrent spy processes.
85 
86  // Open a server socket looking for connections on a named service or
87  // on a specified port
88  //TServerSocket *ss = new TServerSocket("spyserv", kTRUE);
89  fServ = new TServerSocket(9090, kTRUE);
90  if (!fServ->IsValid())
91  gSystem->Exit(1);
92 
93  // Add server socket to monitor so we are notified when a client needs to be
94  // accepted
95  fMon = new TMonitor;
96  fMon->Add(fServ);
97 
98  // Create a list to contain all client connections
99  fSockets = new TList;
100 
101  // Create a new canvas
102  fCanvas = new TCanvas("SpyServ","SpyServ",200,10,700,500);
103  fCanvas->SetFillColor(42);
104  fCanvas->GetFrame()->SetFillColor(21);
105  fCanvas->GetFrame()->SetBorderSize(6);
106  fCanvas->GetFrame()->SetBorderMode(-1);
107 
108  // Create a 1-D, 2-D and a profile histogram
109  fHpx = new TH1F("hpx","This is the px distribution",100,-4,4);
110  fHpxpy = new TH2F("hpxpy","py vs px",40,-4,4,40,-4,4);
111  fHprof = new TProfile("hprof","Profile of pz versus px",100,-4,4,0,20);
112 
113  // Set canvas/frame attributes (save old attributes)
114  fHpx->SetFillColor(48);
115 
116  // Fill histograms randomly
117  gRandom->SetSeed();
118  Float_t px, py, pz;
119  const Int_t kUPDATE = 1000;
120  for (Int_t i = 0; ; i++) {
121  gRandom->Rannor(px,py);
122  pz = px*px + py*py;
123  fHpx->Fill(px);
124  fHpxpy->Fill(px,py);
125  fHprof->Fill(px,pz);
126  if (i && (i%kUPDATE) == 0) {
127  if (i == kUPDATE) fHpx->Draw();
128  fCanvas->Modified();
129  fCanvas->Update();
130 
131  // Check if there is a message waiting on one of the sockets.
132  // Wait not longer than 20ms (returns -1 in case of time-out).
133  TSocket *s;
134  if ((s = fMon->Select(20)) != (TSocket*)-1)
135  HandleSocket(s);
136  if (!fCanvas->TestBit(TObject::kNotDeleted))
137  break;
138  if (gROOT->IsInterrupted())
139  break;
140  }
141  }
142 }
143 
144 SpyServ::~SpyServ()
145 {
146  // Clean up
147 
148  fSockets->Delete();
149  delete fSockets;
150  delete fServ;
151  delete fCanvas;
152  delete fHpx;
153  delete fHpxpy;
154  delete fHprof;
155 }
156 
157 void spyserv()
158 {
159  new SpyServ;
160 }
object has not been deleted
Definition: TObject.h:71
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
float Float_t
Definition: RtypesCore.h:53
const char * GetHostName() const
Definition: TInetAddress.h:71
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition: TSocket.cxx:520
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:818
THist< 1, float, THistStatContent, THistStatUncertainty > TH1F
Definition: THist.hxx:311
#define gROOT
Definition: TROOT.h:375
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor&#39;s active list.
Definition: TMonitor.cxx:168
tomato 1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:551
int Int_t
Definition: RtypesCore.h:41
Profile Histogram.
Definition: TProfile.h:32
void Class()
Definition: Class.C:29
virtual void SetSeed(ULong_t seed=0)
Set the random generator seed.
Definition: TRandom.cxx:568
void Error(const char *location, const char *msgfmt,...)
A doubly linked list.
Definition: TList.h:43
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:176
virtual Int_t Select(Int_t interest=kRead, Long_t timeout=-1)
Waits for this socket to change status.
Definition: TSocket.cxx:441
R__EXTERN TSystem * gSystem
Definition: TSystem.h:539
tomato 2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:249
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
The Canvas class.
Definition: TCanvas.h:31
virtual void Exit(int code, Bool_t mode=kTRUE)
Exit the application.
Definition: TSystem.cxx:723
TInetAddress GetInetAddress() const
Definition: TSocket.h:127
THist< 2, float, THistStatContent, THistStatUncertainty > TH2F
Definition: THist.hxx:317
const Bool_t kTRUE
Definition: RtypesCore.h:91