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