//--------------------------------------------------------------------------- #include #pragma hdrstop #include "CtrlElemento.h" #include "CtrlSocket.h" #include "CtrlPPal.h" #pragma package(smart_init) //--------------------------------------------------------------------------- // Important: Methods and properties of objects in VCL can only be // used in a method called using Synchronize, for example: // // Synchronize(UpdateCaption); // // where UpdateCaption could look like: // // void __fastcall ThreadSocket::UpdateCaption() // { // Form1->Caption = "Updated in a thread"; // } //--------------------------------------------------------------------------- __fastcall ThreadSocket::ThreadSocket(bool CreateSuspended) : TThread(CreateSuspended) { CtrlCOP = 0; FreeOnTerminate = false; } //--------------------------------------------------------------------------- void __fastcall ThreadSocket::SetSocket( AnsiString IP_dst, int Socket ) { ClientSocket = new TClientSocket( CtrlPPal->Owner ); ClientSocket->OnConnect = SocketConnect; ClientSocket->OnDisconnect = SocketDisconnect; ClientSocket->OnError = SocketError; ClientSocket->ClientType = ctBlocking; ClientSocket->Address = IP_dst; ClientSocket->Port = Socket; SocketCreated = true; } //--------------------------------------------------------------------------- void __fastcall ThreadSocket::SocketDisconnect(TObject *Sender, TCustomWinSocket *Socket) { CtrlPPal->Memo1->Lines->Insert( 0, (Now()).DateTimeString() + " :: Tramites Finalizados " + Socket->LocalAddress + " :: " + ClientSocket->Address ); } //--------------------------------------------------------------------------- void __fastcall ThreadSocket::SocketError(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode) { if ( OWNER_Element ) { OWNER_Element->StatusCode = ERROR; // Estamos en proceso de COMPROBACION / ERROR OWNER_Element->BlinkCode = IP_OFF; // --- ERROR INTENTANDO COMUNICAR -- // OWNER_Element->Blink->Enabled = true; // Activamos el parpadeo OWNER_Element->Blink->Interval = 500; } CtrlPPal->Memo1->Lines->Insert( 0, (Now()).DateTimeString() + " :: Cliente ˇ ERROR ! " + AnsiString( ErrorCode ) + "::" + Socket->LocalAddress + " :: " + ClientSocket->Address ); ErrorCode = 0; ClientSocket->Active = false; } //--------------------------------------------------------------------------- void __fastcall ThreadSocket::SocketConnect(TObject *Sender, TCustomWinSocket *Socket) { TWinSocketStream *pStream; CtrlPPal->Memo1->Lines->Insert( 0, (Now()).DateTimeString() + " :: Cliente Conectado ::" + Socket->LocalAddress + " :: " + ClientSocket->Address ); // create a TWinSocketStream for reading and writing pStream = new TWinSocketStream( Socket, 60000 ); try { // fetch and process commands until the connection or thread is terminated if ( !Terminated && ClientSocket->Active ) { try { int CodOp; double doubleT = (double)CtrlTiempo; CodOp = (CtrlCOP == QueryTIME) ? 6661 : (CtrlCOP == CloseWINDOWS) ? 6660 : (CtrlCOP == SettingSTATUS ) ? 6669 : (CtrlCOP == sendLIST) ? 6662 : 0; pStream->Write( &CodOp, sizeof(int) ); switch( CtrlCOP ) { case QueryTIME: double dTiempoInicio; pStream->WaitForData(30000); pStream->Read( &doubleT, sizeof(double) ); pStream->WaitForData(30000); pStream->Read( &dTiempoInicio, sizeof(double) ); if ( OWNER_Element ) OWNER_Element->ClientTimeIs( doubleT, dTiempoInicio ); // Comunicamos el tiempo que dice tener el Clt. CtrlPPal->Memo1->Lines->Insert( 0, (Now()).DateTimeString() + " :: Peticion de Tiempo " + Socket->LocalAddress + " :: " + ClientSocket->Address ); break; case CloseWINDOWS: CodOp = CtrlState; pStream->Write( &CodOp, sizeof(int) ); pStream->Write( &doubleT, sizeof(double) ); if ( OWNER_Element ) { OWNER_Element->StatusCode = ERROR; // Estamos en proceso de COMPROBACION / ERROR OWNER_Element->BlinkCode = IP_OFF; // --- ERROR INTENTANDO COMUNICAR -- OWNER_Element->Blink->Interval = 500; } CtrlPPal->Memo1->Lines->Insert( 0, (Now()).DateTimeString() + " :: Cierre de Windows " + Socket->LocalAddress + " :: " + ClientSocket->Address ); break; case SettingSTATUS: CodOp = CtrlState; pStream->Write( &CodOp, sizeof(int) ); pStream->Write( &doubleT, sizeof(double) ); if ( OWNER_Element ) { OWNER_Element->BlinkCode = NONE; // Desactivamos el parpadeo OWNER_Element->StatusCode = CtrlState ? WORKING : FREE;// Estamos en proceso de COLOCAR ESTADO OWNER_Element->Blink->Interval = 60000; OWNER_Element->ShowElementInfo(); // Contabilizamos la conexión if ( CtrlState ) OWNER_Element->HistoricoTermON( CtrlTiempo ); } CtrlPPal->Memo1->Lines->Insert( 0, (Now()).DateTimeString() + " :: Cambio de estado (" + (CtrlState ? "ON":"OFF") + ")" + Socket->LocalAddress + " :: " + ClientSocket->Address ); break; case sendLIST: CodOp = CtrlPPal->siMinimizar->Count; // CtrlPPal->Memo1->Lines->Insert( 0, "Elementos A: " + AnsiString( CodOp ) ); pStream->Write( &CodOp, sizeof(int) ); for ( int i=0; iWrite( (void *)((CtrlPPal->siMinimizar->Strings[i]).c_str()), sizeof(char)*15 ); CodOp = CtrlPPal->noMinimizar->Count; pStream->Write( &CodOp, sizeof(int) ); for ( int i=0; iWrite( (void *)((CtrlPPal->noMinimizar->Strings[i]).c_str()), sizeof(char)*15 ); CodOp = CtrlPPal->snMinimizar->Count; pStream->Write( &CodOp, sizeof(int) ); for ( int i=0; iWrite( (void *)((CtrlPPal->snMinimizar->Strings[i]).c_str()), sizeof(char)*15 ); CodOp = CtrlPPal->noAbrir->Count; pStream->Write( &CodOp, sizeof(int) ); for ( int i=0; iWrite( (void *)((CtrlPPal->noAbrir->Strings[i]).c_str()), sizeof(char)*15 ); break; default: break; } pStream->WaitForData(30000); pStream->Read( &CodOp, sizeof(int) ); if ( CodOp != 54321 ) { CtrlPPal->Memo1->Lines->Insert( 0, (Now()).DateTimeString() + " :: Cliente RESPONDE ANORMALMENTE " + Socket->LocalAddress ); } } catch (Exception &E) { if (!E.ClassNameIs("EAbort")) { if ( OWNER_Element ) { OWNER_Element->StatusCode = ERROR; // Estamos en proceso de COMPROBACION / ERROR OWNER_Element->BlinkCode = IP_OFF; // --- ERROR INTENTANDO COMUNICAR -- // OWNER_Element->Blink->Enabled = true; // Activamos el parpadeo OWNER_Element->Blink->Interval = 500; } CtrlPPal->Memo1->Lines->Insert( 0, (Now()).DateTimeString() + " :: Error en el HILO de " + Socket->LocalAddress ); } } } } __finally { delete pStream; OWNER_Element = NULL; Socket->Close(); } } //--------------------------------------------------------------------------- void __fastcall ThreadSocket::Execute() { if ( SocketCreated ) { CtrlPPal->AnySocketActive++; try { ClientSocket->Active = true; } catch (Exception &E) { if (!E.ClassNameIs("EAbort")) { if ( OWNER_Element ) { OWNER_Element->StatusCode = ERROR; // Estamos en proceso de COMPROBACION / ERROR OWNER_Element->BlinkCode = IP_OFF; // --- ERROR INTENTANDO COMUNICAR -- // OWNER_Element->Blink->Enabled = true; // Activamos el parpadeo OWNER_Element->Blink->Interval = 500; } CtrlPPal->Memo1->Lines->Insert( 0, (Now()).DateTimeString() + " :: Error en el HILO de " + ClientSocket->Address + " (" + E.Message+")" ); // you must write HandleThreadException } } while ( !Terminated && ClientSocket->Active ); // Do nothing CtrlPPal->AnySocketActive--; } } //--------------------------------------------------------------------------- ////////////////// GESTION DE LOS HILOS DE COMUNICACIÓN ///////////////////// void __fastcall ThreadSocket::Terminate(TObject *Sender) // this is the OnTerminate handler { if ( SocketCreated ) { if ( ClientSocket->Active ) ClientSocket->Active = false; delete ClientSocket; SocketCreated = false; } pCache->Add( this ); // add pointer to this thread to the cache } //--------------------------------------------------------------------------- //########################################################################### //########################################################################### //###########################################################################