How to create a stream of TObject?

I would like to create stream of TObject. Possibly a bunch of TObjects (maybe a TDirectory?) including some custom classes inheriting from TObject.

I have seen these examples in root documentation:
https://root.cern/doc/master/pclient_8C.html
ROOT: tutorials/net/pserv.C File Reference (not working…)
ROOT: tutorials/net/hclient.C File Reference
ROOT: tutorials/net/hserv2.C File Reference
ROOT: tutorials/net/hserv.C File Reference

I think what suits what I would like to do is the pclient/pserv…, but with TObject… ?
I basically want to open a “StreamServer” and let as many people to connect as “StreamClient” program are running.

This program would send every X seconds an histogram… and all clients will receive it…
Does it make sense ? Anybody could help me with that? So far I couldnt make pserv.C running.

I have tried to adapt and fix the issue in pserver.C

void pserv()
{
   // Open a parallel server socket looking for connections on a named
   // service or on a specified port.
   TPServerSocket *ss = new TPServerSocket(9090, kTRUE);
 
   // Accept a connection and return a full-duplex communication socket.
   TPSocket *sock = (TPSocket*) ss->Accept();
   delete ss;
 
   int niter, bsize;
   sock->Recv(niter, bsize);
 
   printf("Receive %d buffers of %d bytes over %d parallel sockets...\n",
          niter, bsize, sock->GetSize());
 
   char *buf = new char[bsize];
 
   // start timer
   TStopwatch timer;
   timer.Start();
 
   // accept data from client
   for (int i = 0; i < niter; i++) {
      memset(buf, 0, bsize);
      int ret = sock->RecvRaw(buf, bsize, ESendRecvOptions::kDefault);
      if (ret < 0) {
         printf("error receiving\n");
         break;
      }
      if (buf[0] != 65) {
         printf("received data corrupted\n");
         break;
      }
   }
 
   delete sock;
   delete [] buf;
 
   // stop timer and print results
   timer.Stop();
   Double_t rtime = timer.RealTime();
   Double_t ctime = timer.CpuTime();
 
   printf("%d bytes received in %f seconds\n", niter*bsize, rtime);
   if (rtime > 0) printf("%5.2f MB/s\n", Double_t(niter*bsize/1024/1024)/rtime);
}

void pclient(int niter = 100, int bsize = 500000, int nsocks = 5)
{
   // Open connection to server
   TPSocket *sock = new TPSocket("localhost", 9090, nsocks);

   char *buf = new char[bsize];
   memset(buf, 65, bsize);

   sock->Send(niter, bsize);

   // send data to server
   for (int i = 0; i < niter; i++) {
      int ret = sock->SendRaw(buf, bsize, ESendRecvOptions::kDefault);
      if (ret < 0) {
         printf("error sending\n");
         break;
      }
   }

   delete sock;
   delete [] buf;
}

but I get an error message on client side…

root [1] .x pclient.C
Warning in <TPSocket::Init>: problems sending size

Maybe ROOT: tutorials/net/spyserv.C File Reference is more appropriate ?

Hi! I was looking into this, and proposed a fix for the tutorials:

As you can see in the PR review, TPSocket* should be considered as legacy and not be used. To stream objects, “please use one of the many network libraries instead, such as Boost Asio”.

Is that also a solution for you?

Cheers,
Jonas

Hi Jonas, thank you so much for creating this branch yesterday !

The answer is a bit disappointing… @Axel why is it that TPSocket should be legacy ?
Does it mean TSocket is about to be considered as legacy too ??

Hi,

You also can use THttpServer class of ROOT, which provides different way of objects streaming.

One can get json, xml or binary form for any object registered to the server.
Check examples in tutorials/http/ directory and read documentation:

Regards,
Sergey

Legacy isn’t deprecation: we will keep the code, but we recommend against its use in new projects. We have inadequate test coverage, we know it cannot compete with today’s networking libraries, and we don’t intend to do anything to this code except to maintain it.

The way to go for streaming TObject is to write it to a TBuffer and then transfer that buffer through your favorite networking library.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.