spyserv.C

Go to the documentation of this file.
00001 // Server program which allows clients, "spies", to connect and snoop objects.
00002 // To run this demo do the following:
00003 //   - open two or more windows
00004 //   - start root in all windows
00005 //   - execute in the first window:    .x spyserv.C  (or spyserv.C++)
00006 //   - execute in the other window(s): .x spy.C      (or spy.C++)
00007 //   - in the "spy" client windows click the "Connect" button and snoop
00008 //     the histograms by clicking on the "hpx", "hpxpy" and "hprof"
00009 //     buttons
00010 //Author: Fons Rademakers
00011    
00012 #include "TH1.h"
00013 #include "TH2.h"
00014 #include "TProfile.h"
00015 #include "TCanvas.h"
00016 #include "TFrame.h"
00017 #include "TSocket.h"
00018 #include "TServerSocket.h"
00019 #include "TMonitor.h"
00020 #include "TMessage.h"
00021 #include "TRandom.h"
00022 #include "TList.h"
00023 #ifndef __CINT__
00024 #include "TError.h"
00025 #endif
00026 
00027 
00028 class SpyServ {
00029 private:
00030    TCanvas       *fCanvas;    // main canvas
00031    TH1F          *fHpx;       // 1-D histogram
00032    TH2F          *fHpxpy;     // 2-D histogram
00033    TProfile      *fHprof;     // profile histogram
00034    TServerSocket *fServ;      // server socket
00035    TMonitor      *fMon;       // socket monitor
00036    TList         *fSockets;   // list of open spy sockets
00037 public:
00038    SpyServ();
00039    ~SpyServ();
00040 
00041    void HandleSocket(TSocket *s);
00042 };
00043 
00044 
00045 void SpyServ::HandleSocket(TSocket *s)
00046 {
00047    if (s->IsA() == TServerSocket::Class()) {
00048       // accept new connection from spy
00049       TSocket *sock = ((TServerSocket*)s)->Accept();
00050       fMon->Add(sock);
00051       fSockets->Add(sock);
00052       printf("accepted connection from %s\n", sock->GetInetAddress().GetHostName());
00053    } else {
00054       // we only get string based requests from the spy
00055       char request[64];
00056       if (s->Recv(request, sizeof(request)) <= 0) {
00057          fMon->Remove(s);
00058          fSockets->Remove(s);
00059          printf("closed connection from %s\n", s->GetInetAddress().GetHostName());
00060          delete s;
00061          return;
00062       }
00063 
00064       // send requested object back
00065       TMessage answer(kMESS_OBJECT);
00066       if (!strcmp(request, "get hpx"))
00067          answer.WriteObject(fHpx);
00068       else if (!strcmp(request, "get hpxpy"))
00069          answer.WriteObject(fHpxpy);
00070       else if (!strcmp(request, "get hprof"))
00071          answer.WriteObject(fHprof);
00072       else
00073          Error("SpyServ::HandleSocket", "unexpected message");
00074       s->Send(answer);
00075    }
00076 }
00077 
00078 SpyServ::SpyServ()
00079 {
00080    // Create the server process to fills a number of histograms.
00081    // A spy process can connect to it and ask for the histograms.
00082    // There is no apriory limit for the number of concurrent spy processes.
00083 
00084    // Open a server socket looking for connections on a named service or
00085    // on a specified port
00086    //TServerSocket *ss = new TServerSocket("spyserv", kTRUE);
00087    fServ = new TServerSocket(9090, kTRUE);
00088    if (!fServ->IsValid())
00089       gSystem->Exit(1);
00090 
00091    // Add server socket to monitor so we are notified when a client needs to be
00092    // accepted
00093    fMon  = new TMonitor;
00094    fMon->Add(fServ);
00095 
00096    // Create a list to contain all client connections
00097    fSockets = new TList;
00098 
00099    // Create a new canvas
00100    fCanvas = new TCanvas("SpyServ","SpyServ",200,10,700,500);
00101    fCanvas->SetFillColor(42);
00102    fCanvas->GetFrame()->SetFillColor(21);
00103    fCanvas->GetFrame()->SetBorderSize(6);
00104    fCanvas->GetFrame()->SetBorderMode(-1);
00105 
00106    // Create a 1-D, 2-D and a profile histogram
00107    fHpx    = new TH1F("hpx","This is the px distribution",100,-4,4);
00108    fHpxpy  = new TH2F("hpxpy","py vs px",40,-4,4,40,-4,4);
00109    fHprof  = new TProfile("hprof","Profile of pz versus px",100,-4,4,0,20);
00110 
00111    //  Set canvas/frame attributes (save old attributes)
00112    fHpx->SetFillColor(48);
00113 
00114    // Fill histograms randomly
00115    gRandom->SetSeed();
00116    Float_t px, py, pz;
00117    const Int_t kUPDATE = 1000;
00118    for (Int_t i = 0; ; i++) {
00119       gRandom->Rannor(px,py);
00120       pz = px*px + py*py;
00121       fHpx->Fill(px);
00122       fHpxpy->Fill(px,py);
00123       fHprof->Fill(px,pz);
00124       if (i && (i%kUPDATE) == 0) {
00125          if (i == kUPDATE) fHpx->Draw();
00126          fCanvas->Modified();
00127          fCanvas->Update();
00128 
00129          // Check if there is a message waiting on one of the sockets.
00130          // Wait not longer than 20ms (returns -1 in case of time-out).
00131          TSocket *s;
00132          if ((s = fMon->Select(20)) != (TSocket*)-1)
00133             HandleSocket(s);
00134          if (!fCanvas->TestBit(TObject::kNotDeleted))
00135             break;
00136          if (gROOT->IsInterrupted())
00137             break;
00138       }
00139    }
00140 }
00141 
00142 SpyServ::~SpyServ()
00143 {
00144    // Clean up
00145 
00146    fSockets->Delete();
00147    delete fSockets;
00148    delete fServ;
00149    delete fCanvas;
00150    delete fHpx;
00151    delete fHpxpy;
00152    delete fHprof;
00153 }
00154 
00155 void spyserv()
00156 {
00157    new SpyServ;
00158 }

Generated on Tue Jul 5 15:44:52 2011 for ROOT_528-00b_version by  doxygen 1.5.1