Z
Danke Doc!!! Das Thema ist nun endgültig erledigt. Innerhalb von Events eines Klassenobjektes die Klasse freizugeben bzw. innerhalb eines Events das Sender Objekt freizugeben ohne das beide Szenarieren vollständig abgearbeitet waren, war gelinde gesagt sehr ungeschickt von mir. Wie war das mit dem Ast absägen worauf man sitzt???
Ich habe nun alle erdenklichen Möglichkeiten von Socket Errors und Disconnects auf beiden Seiten durchgetestet und weder eine Exception oder ein Speicherleck treten auf. Habe es so umgeschrieben das das Serversocket die alleinige Kontrolle über new und delete der Klasseninstanzen hat. Codeguard ist nun genauso zufrieden wie ich
YarccSession::YarccSession(TCustomWinSocket *serversocket)
:myserversocket(serversocket)
{
Form1->Memo4->Lines->Add("Konstruktor YarccSession");
this->myserversocket->Data = this;
this->myclientsocket = new TClientSocket(NULL);
this->myclientsocket->Socket->Data = this;
this->myclientsocket->ClientType = ctNonBlocking;
this->myclientsocket->Host = "90.192.150.231";
this->myclientsocket->Port = 25505;
this->myclientsocket->OnConnect = myclientsocket1Connect;
this->myclientsocket->OnDisconnect = myclientsocket1Disconnect;
this->myclientsocket->OnError = myclientsocket1Error;
this->myclientsocket->OnRead = myclientsocket1Read;
this->myclientsocket->Open();
}
//----------------------------------------
//--- Destruktor der Klasse ClientSession
//----------------------------------------
YarccSession::~YarccSession()
{
Form1->Memo4->Lines->Add("Destruktor YarccSession");
delete this->myclientsocket;
this->myclientsocket = NULL;
}
//--------------------------------------------------------------
//---------------------------------------------------------------------------
//------- CLIENT
//---------------------------------------------------------------------------
void __fastcall YarccSession::myclientsocket1Connect(TObject *Sender,
TCustomWinSocket *Socket)
{
Form1->Memo4->Lines->Add(Time().TimeString() + " [ClientSession] Connected");
}
//---------------------------------------------------------------------------
void __fastcall YarccSession::myclientsocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
YarccSession *asession = (YarccSession*) Socket->Data;
std::vector<unsigned char> ReceiveBuffer(Socket->ReceiveLength(),0);
if(!ReceiveBuffer.empty())
{
int Received = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
if( Received > 0 )
{
ReceiveBuffer.resize(Received);
asession->ClientPaketsammler.insert( asession->ClientPaketsammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.begin() + Received );
ClientHandleReceivedPackets(Socket);
}
}
}
//---------------------------------------------------------------------------
void __fastcall YarccSession::ClientHandleReceivedPackets(TCustomWinSocket *Socket)
{
YarccSession *asession = (YarccSession*) Socket->Data;
unsigned int SequenceId;
while(asession->ClientPaketsammler.size() >= 8 )
{
unsigned int TelegramLength = asession->ClientPaketsammler[4] | asession->ClientPaketsammler[5] << 8 | asession->ClientPaketsammler[6] << 16 | asession->ClientPaketsammler[7] << 24;
if( asession->ClientPaketsammler.size() < TelegramLength )
return;
SequenceId = asession->ClientPaketsammler[0] | asession->ClientPaketsammler[1] << 8 | asession->ClientPaketsammler[2] << 16 | asession->ClientPaketsammler[3] << 24;
SequenceId = SequenceId & 0x3fffffff;
std::vector<unsigned char> Paket(asession->ClientPaketsammler.begin(), asession->ClientPaketsammler.begin() + TelegramLength);
Paket.resize(TelegramLength);
//Vom Master Server kommenden an den entsprechenden Client weiterleiten
asession->myserversocket->SendBuf(&Paket[0],Paket.size());
asession->ClientPaketsammler.erase( asession->ClientPaketsammler.begin(), asession->ClientPaketsammler.begin() + TelegramLength );
}
}
//------------------------------------------------------------------------------------------------------
void __fastcall YarccSession::myclientsocket1Disconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
if(Socket->Data != NULL)
{
YarccSession *asession = (YarccSession*)Socket->Data;
if(asession->myserversocket->Connected)
asession->myserversocket->Close();
}
Form1->Memo4->Lines->Add(Time().TimeString() + " [ClientSession] Disconnected");
}
//---------------------------------------------------------------------------
void __fastcall YarccSession::myclientsocket1Error(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
if(Socket->Data != NULL)
{
YarccSession *asession = (YarccSession*)Socket->Data;
if(asession->myserversocket->Connected)
asession->myserversocket->Close();
}
Form1->Memo4->Lines->Add(Time().TimeString() + " [ClientSession] Socket Error: " + String(ErrorCode)) ;
ErrorCode = 0;
}
//--------------------------------------------------------------------------
//---------------------------------------------------------------------------
//----------- SERVER
//---------------------------------------------------------------------------
void __fastcall TForm1::Button14Click(TObject *Sender)
{
if(Button14->Caption == "Start")
{
Button14->Caption = "Stop";
ServerSocket1 = new TServerSocket(Form1);
ServerSocket1->ServerType = stNonBlocking;
ServerSocket1->OnClientConnect = ServerSocket1Connect;
ServerSocket1->OnClientRead = ServerSocket1ClientRead;
ServerSocket1->OnClientDisconnect = ServerSocket1ClientDisconnect;
ServerSocket1->OnClientError = ServerSocket1ClientError;
ServerSocket1->Port = 14888;
ServerSocket1->Active = true;
}
else
{
Button14->Caption = "Start";
if(ServerSocket1->Socket->ActiveConnections > 0)
{
for(int i = 0; i < ServerSocket1->Socket->ActiveConnections; i++)
{
ServerSocket1->Socket->Disconnect(i);
}
}
ServerSocket1->Active = false;
delete ServerSocket1;
}
}
//------------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
YarccSession *asession = (YarccSession *)Socket->Data;
std::vector<unsigned char> ReceiveBuffer(Socket->ReceiveLength(), 0 );
if( !ReceiveBuffer.empty() )
{
int Received = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size());
if(Received > 0)
{
ReceiveBuffer.resize(Received);
asession->ServerPaketsammler.insert(asession->ServerPaketsammler.end(), ReceiveBuffer.begin(),ReceiveBuffer.begin() + Received);
asession->ServerHandleReceivedPackets(Socket);
}
}
}
//---------------------------------------------------------------------------------------------------------
void __fastcall YarccSession::ServerHandleReceivedPackets(TCustomWinSocket *Socket)
{
YarccSession *asession = (YarccSession*)Socket->Data;
unsigned int SequenceId;
while(asession->ServerPaketsammler.size() >= 8 )
{
unsigned int TelegramLength = asession->ServerPaketsammler[4] | asession->ServerPaketsammler[5] << 8 |
asession->ServerPaketsammler[6] << 16 | asession->ServerPaketsammler[7] << 24;
if( asession->ServerPaketsammler.size() < TelegramLength )
return;
SequenceId = asession->ServerPaketsammler[0] | asession->ServerPaketsammler[1] << 8 | asession->ServerPaketsammler[2] << 16
| asession->ServerPaketsammler[3] << 24;
SequenceId = SequenceId & 0x3fffffff;
std::vector<unsigned char>Paket(asession->ServerPaketsammler.begin(), asession->ServerPaketsammler.begin() + TelegramLength );
Paket.resize(TelegramLength);
//******** Packet vom Client kommend an Master Server weiterleiten
asession->myclientsocket->Socket->SendBuf(&Paket[0],Paket.size());
asession->ServerPaketsammler.erase( asession->ServerPaketsammler.begin(), asession->ServerPaketsammler.begin() + TelegramLength );
}
}
//----------------------------------------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1Connect(TObject *Sender,
TCustomWinSocket *Socket)
{
new YarccSession(Socket);
Form1->Memo4->Lines->Add(Time().TimeString() + " [YARCC Client] Connected");
}
//--------------------------------------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientDisconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
if(Socket->Data != NULL)
{
YarccSession *asession = (YarccSession*)Socket->Data;
if(asession->myclientsocket->Socket->Connected)
{
asession->myclientsocket->Socket->Data = NULL;
asession->myclientsocket->Socket->Close();
}
delete asession;
asession = NULL;
}
Form1->Memo4->Lines->Add(Time().TimeString() + " [YARCC Client] Disconnected");
}
//--------------------------------------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientError(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
YarccSession *asession = (YarccSession*)Socket->Data;
if(asession->myserversocket->Connected)
asession->myserversocket->Close();
Form1->Memo4->Lines->Add(Time().TimeString() + " [YARCC Client] Socket Error: " + String(ErrorCode)) ;
ErrorCode = 0;
}
//--------------------------------------------------------------------------------------------------------