00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "TGo4Socket.h"
00017
00018 #include "Riostream.h"
00019
00020 #include "snprintf.h"
00021 #include "TMutex.h"
00022 #include "TMessage.h"
00023 #include "TSystem.h"
00024 #include "TSocket.h"
00025 #include "TServerSocket.h"
00026 #include "RVersion.h"
00027
00028 #include "TGo4Log.h"
00029 #include "TGo4LockGuard.h"
00030 #include "TGo4SocketSignalHandler.h"
00031 #include "TGo4Buffer.h"
00032
00033 const Int_t TGo4Socket::fguOPENWAIT=200;
00034 const Int_t TGo4Socket::fgiOPENCYCLES=6;
00035 const Int_t TGo4Socket::fgiBUFLENGTH=256;
00036 const Int_t TGo4Socket::fgiBUFINITSIZE=65536;
00037 const Int_t TGo4Socket::fgiBUFEXTRASPACE=8;
00038 const char* TGo4Socket::fgcGOON = "-I- go on";
00039
00040
00041 #if ROOT_VERSION_CODE > ROOT_VERSION(4,3,2)
00042
00043 const Int_t TGo4Socket::fgiISOWNER=TBuffer::kIsOwner;
00044 #else
00045 const Int_t TGo4Socket::fgiISOWNER=BIT(14);
00046
00047 #endif
00048
00049
00050
00051 TGo4Socket::TGo4Socket(Bool_t IsClient)
00052 : fbClientMode(IsClient), fbOpen(kFALSE),
00053 fxSocket(0), fxServerSocket(0), fiPort(0)
00054 {
00055 TRACE((14,"TGo4Socket::TGo4Socket(Bool_t)", __LINE__, __FILE__));
00056
00057 fxBuffer= new TGo4Buffer(TBuffer::kRead, TGo4Socket::fgiBUFINITSIZE);
00058 fxSignalHandler= new TGo4SocketSignalHandler(SIGWINCH);
00059 fxLocalBuffer = new Text_t [TGo4Socket::fgiBUFLENGTH];
00060 if(fbClientMode)
00061 {
00062 TGo4Log::Debug(" Created new Go4Socket in client mode ");
00063 }
00064 else
00065 {
00066 TGo4Log::Debug(" Created new Go4Socket in server mode ");
00067 }
00068 }
00069
00070 TGo4Socket::~TGo4Socket()
00071 {
00072 TRACE((14,"TGo4Socket::~TGo4Socket()", __LINE__, __FILE__));
00073 delete [] fxLocalBuffer;
00074 if(fxSocket)
00075 {
00076 fxSocket->Close();
00077 delete fxSocket;
00078 }
00079
00080 if(fxServerSocket)
00081 {
00082 fxServerSocket->Close();
00083 delete fxServerSocket;
00084 }
00085 delete fxSignalHandler;
00086 }
00087
00088 Int_t TGo4Socket::Open(const char* host, Int_t port, Bool_t keepservsock)
00089 {
00090 TRACE((12,"TGo4Socket::Open(Text_t *host, Int_t port)", __LINE__, __FILE__));
00091
00092 Int_t rev=0;
00093 if(!fbOpen)
00094 {
00095 if(fbClientMode)
00096 {
00097
00098 fxSocket = new TSocket(host, port);
00099 Int_t maxcounter=0;
00100 while(!fxSocket->IsValid())
00101 {
00102 if(++maxcounter> TGo4Socket::fgiOPENCYCLES)
00103 {
00104 TGo4Log::Debug(" Socket: Open timeout!!");
00105 break;
00106 }
00107 else
00108 {
00109 TGo4Log::Debug(" Socket: Open retry %d ", maxcounter);
00110 delete fxSocket;
00111 gSystem->Sleep(TGo4Socket::fguOPENWAIT);
00112 fxSocket = new TSocket(host, port);
00113 }
00114 }
00115 if(!fxSocket->IsValid())
00116 {
00117 TGo4Log::Debug(" Socket: Open(Text_t *host, Int_t port ) as Client failed ");
00118 fiPort=0;
00119 return -8;
00120 }
00121 else
00122 {
00123 fxSocket->SetOption(kNoBlock,0);
00124 fiPort=fxSocket->GetLocalPort();
00125 }
00126 char str[32];
00127 fxSocket->Recv(str, 32);
00128 if(!strcmp(str,TGo4Socket::fgcGOON))
00129 {
00130
00131 fbOpen = kTRUE;
00132 rev=0;
00133 TGo4Log::Debug(" Socket: Connection Established ");
00134 }
00135 else
00136 {
00137 TGo4Log::Debug(" Socket: !!! Received unknown string !!! ");
00138 }
00139 }
00140 else
00141 {
00142
00143 if(!fxServerSocket)
00144 {
00145 fxServerSocket = new TServerSocket(port, kFALSE);
00146 fxServerSocket->SetOption(kNoBlock,1);
00147 }
00148 else
00149 {
00150
00151 }
00152 if(!fxServerSocket->IsValid())
00153 {
00154 TGo4Log::Debug(" Socket: Open(Text_t *host, Int_t port) as Server failed ");
00155 fiPort=0;
00156 return -8;
00157 }
00158 else
00159 {
00160 fiPort=fxServerSocket->GetLocalPort();
00161
00162 }
00163 fxSocket = 0;
00164 while(1)
00165 {
00166 if(!fxSocket)
00167 {
00168 fxSocket = fxServerSocket->Accept();
00169 if(!fxSocket || fxSocket==(TSocket*) (-1) )
00170 {
00171 fxSocket=0;
00172 rev=-1;
00173 break;
00174
00175 }
00176 else
00177 {
00178 fxSocket->SetOption(kNoBlock,0);
00179 fxSocket->Send(TGo4Socket::fgcGOON);
00180 if(!keepservsock)
00181 {
00182 fxServerSocket->Close();
00183 delete fxServerSocket;
00184 fxServerSocket = 0;
00185 }
00186 else
00187 {
00188
00189
00190
00191 }
00192 fbOpen = kTRUE;
00193 rev=0;
00194 break;
00195 }
00196 }
00197 else
00198 {
00199 rev=-2;
00200 break;
00201 }
00202 }
00203 }
00204 }
00205 else
00206 {
00207 rev=1;
00208 }
00209 return rev;
00210 }
00211
00212
00213 Int_t TGo4Socket::Close(Option_t *opt)
00214 {
00215 TRACE((12,"TGo4Socket::Close()", __LINE__, __FILE__));
00216 Int_t rev=0;
00217 if(fbOpen)
00218 {
00219 fxSocket->Close(opt);
00220 fbOpen = kFALSE;
00221 rev = 0;
00222 }
00223 else
00224 {
00225 rev = 1;
00226 }
00227 return rev;
00228 }
00229
00230 Int_t TGo4Socket::SendBuffer(TBuffer* buf)
00231 {
00232 TRACE((12,"TGo4Socket::SendBuffer(TBuffer*)", __LINE__, __FILE__));
00233
00234 Int_t rev=0;
00235 if(buf)
00236 {
00237 UInt_t len=buf->Length();
00238
00239 char* field=buf->Buffer();
00240 if(IsOpen())
00241 {
00242 if(fxSocket)
00243 {
00244 if(field)
00245 {
00246 char* temp = field;
00247 tobuf(temp, (UInt_t)(len - sizeof(UInt_t)));
00248
00250
00251
00252
00253
00254
00256 rev=fxSocket->SendRaw(field,len);
00257
00258 if(rev<= 0)
00259 {
00260
00261 TGo4Log::Debug(" !!! Socket: SendBuffer() ERROR # %d !!! ",rev);
00262 return rev;
00263 }
00264 else
00265 {
00266 rev=0;
00267 }
00268 }
00269 else
00270 {
00271 TGo4Log::Debug(" !!! Socket: SendBuffer() ERROR : no data field !!! ");
00272 rev=-5;
00273 }
00274 }
00275 else
00276 {
00277 TGo4Log::Debug(" !!! Socket: SendBuffer() ERROR : no TSocket !!! ");
00278 rev=-5;
00279 }
00280 }
00281 else
00282 {
00283 TGo4Log::Debug(" !!! Socket: SendBuffer() ERROR : socket not open !!! ");
00284 rev=-1;
00285 }
00286 }
00287 else
00288 {
00289 TGo4Log::Debug(" !!! Socket: SendBuffer() ERROR : no buffer !!! ");
00290 rev=-2;
00291 }
00292 return rev;
00293 }
00294
00295 Int_t TGo4Socket::ReceiveBuffer()
00296 {
00297 TRACE((12,"TGo4Socket::ReceiveBuffer()", __LINE__, __FILE__));
00298
00299 Int_t rev=0;
00300 UInt_t len=0;
00301 if(IsOpen())
00302 {
00303 if(fxSocket)
00304 {
00305
00306 rev=fxSocket->RecvRaw(&len, sizeof(UInt_t));
00307 if(rev<= 0)
00308 {
00309
00310
00311
00312 return -55;
00313 }
00314 else
00315 {
00316 }
00317
00318 len = net2host(len);
00319 Int_t messlen = len + sizeof(UInt_t);
00320
00321
00322 Int_t oldsize = fxBuffer->BufferSize();
00323 Int_t newsize = messlen;
00324 if(newsize>oldsize)
00325 {
00326 ReallocBuffer(fxBuffer, oldsize, newsize);
00327 }
00328 else if(newsize<oldsize && oldsize>TGo4Socket::fgiBUFINITSIZE)
00329 {
00330
00331 if(newsize< TGo4Socket::fgiBUFINITSIZE)
00332 newsize= TGo4Socket::fgiBUFINITSIZE;
00333 ReallocBuffer(fxBuffer, oldsize, newsize);
00334 }
00335 else { }
00336
00337 char* buf=fxBuffer->Buffer() +sizeof(UInt_t);
00338
00339 rev=fxSocket->RecvRaw((void*) buf, len);
00340 if(rev<= 0)
00341 {
00342
00343 TGo4Log::Debug(" !!! Socket: ReceiveBuffer() ERROR # %d !!! ",rev);
00344 return -56;
00345 }
00346 else
00347 {
00348
00349
00350 fxBuffer->SetBufferOffset(messlen);
00351 fxBuffer->SetByteCount(0);
00352 rev=0;
00353 }
00354 }
00355 else
00356 {
00357 TGo4Log::Debug(" !!! Socket: ReceiveBuffer() ERROR : no TSocket !!! ");
00358 rev=-10;
00359 }
00360 }
00361 else
00362 {
00363 TGo4Log::Debug(" !!! Socket: ReceiveBuffer() ERROR : not open !!! ");
00364 rev=-11;
00365 }
00366 return rev;
00367 }
00368
00369 Int_t TGo4Socket::Send(TObject *obj)
00370 {
00371 TRACE((12,"TGo4Socket::Send(TObject *obj)", __LINE__, __FILE__));
00372
00373 Int_t rev=0;
00374 if(IsOpen())
00375 {
00376 {
00377 TGo4LockGuard init;
00378 }
00379 TGo4LockGuard::LockMainMutex();
00380 TMessage mess(kMESS_OBJECT);
00381 mess.WriteObject(obj);
00382 TGo4LockGuard::UnLockMainMutex();
00383 if(fxSocket)
00384 {
00385 rev = fxSocket->Send(mess);
00386 }
00387 else
00388 {
00389 rev=-16;
00390 }
00391 }
00392 else
00393 {
00394
00395 rev=-32;
00396 }
00397
00398 if(rev < 0)
00399 {
00400 TGo4Log::Debug(" !!! Socket: Send(TObject*) ERROR # %d !!! ",rev);
00401 }
00402 return rev;
00403 }
00404
00405 Int_t TGo4Socket::Send(const char* name)
00406 {
00407 TRACE((12,"TGo4Socket::Send(const char* name)", __LINE__, __FILE__));
00408
00409 Int_t rev=0;
00410 if(IsOpen())
00411 {
00412 if(fxSocket)
00413 {
00414 snprintf(fxLocalBuffer,TGo4Socket::fgiBUFLENGTH-1, "%s", name);
00415 rev = fxSocket->SendRaw(fxLocalBuffer,TGo4Socket::fgiBUFLENGTH);
00416 }
00417 else
00418 {
00419 rev=-16;
00420 }
00421 }
00422 else
00423 {
00424
00425 rev=-32;
00426 }
00427
00428 if(rev < 0)
00429 {
00430 TGo4Log::Debug(" !!! Socket: Send(const char*) ERROR # %d !!! ",rev);
00431 }
00432 return rev;
00433 }
00434
00435 Text_t* TGo4Socket::RecvRaw(const char* name)
00436 {
00437
00438 TRACE((12,"TGo4Socket::RecvRaw(Text_t *name)", __LINE__, __FILE__));
00439
00440 Text_t* revchar;
00441 if(IsOpen())
00442 {
00443 if(fxSocket)
00444 {
00445 Int_t rev=fxSocket->RecvRaw(fxLocalBuffer, TGo4Socket::fgiBUFLENGTH);
00446 if(rev<= 0)
00447 {
00448
00449 TGo4Log::Debug(" !!! Socket: Recv(Text_t*) ERROR # %d !!! ",rev);
00450 revchar=0;
00451 }
00452 else
00453 {
00454 revchar=fxLocalBuffer;
00455 }
00456 }
00457 else
00458 {
00459 TGo4Log::Debug(" !!! Socket: Recv(const char*) ERROR : no TSocket !!! ");
00460 revchar=0;
00461 }
00462 }
00463 else
00464 {
00465 TGo4Log::Debug(" !!! Socket: Recv(const char*) ERROR : not open or not active !!! ");
00466 revchar=0;
00467 }
00468 return revchar;
00469 }
00470
00471
00472
00473 TObject* TGo4Socket::Recv(const char* name)
00474 {
00475
00476 TRACE((12,"TGo4Socket::Recv(const char* name)", __LINE__, __FILE__));
00477
00478 TObject* obj=0;
00479 Int_t rev=0;
00480 if(IsOpen())
00481 {
00482 TMessage *mess;
00483 if(fxSocket)
00484 {
00485 rev=fxSocket->Recv(mess);
00486 if(mess == 0)
00487 {
00488
00489 obj=0;
00490 }
00491 else
00492 {
00493 TGo4LockGuard socker;
00494 if(mess->What() == kMESS_OBJECT)
00495 {
00496 obj = mess->ReadObject(mess->GetClass());
00497 }
00498 delete mess;
00499 }
00500
00501 }
00502 else
00503 {
00504 TGo4Log::Debug(" !!! Socket: Recv(TMessage*) ERROR : no TSocket! ");
00505 }
00506 }
00507 else
00508 {
00509 TGo4Log::Debug(" !!! Socket: Recv(TMessage*) ERROR : not open or not active! ");
00510 }
00511 return obj;
00512 }
00513
00514
00515 void TGo4Socket::ReallocBuffer(TBuffer* buffer, Int_t oldsize, Int_t newsize)
00516 {
00517 if(buffer==0) return;
00518 TGo4LockGuard mainguard;
00519 char* memfield=buffer->Buffer();
00520
00521
00522 Int_t extraspace=TGo4Socket::fgiBUFEXTRASPACE;
00523
00524
00525
00526
00527 memfield = TStorage::ReAllocChar(memfield,
00528 (newsize+extraspace),
00529 (oldsize+extraspace));
00530
00531 buffer->ResetBit(fgiISOWNER);
00532 buffer->SetBuffer(memfield, newsize);
00533 buffer->SetBit(fgiISOWNER);
00534
00535
00536
00537
00538
00539 buffer->SetBufferOffset(newsize);
00540 }
00541
00542