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