[TServerSocket] Empfangspuffer für jeden verbundenen Client



  • Konnte heute endlich mal wieder etwas weitermachen. Ich habe nun herausgefunden was die beiden Exceptions verursacht. Folgende Zeile im Destruktor YarccSession:

    delete this->myclientsocket;
    

    Jetzt bin ich etwas irretiert. Das TClientSocket ist Member der Klasse. DocShoe hatte schon gefragt warum ich das Objekt manuell freigebe. Kommentiere ich das delete des ClientSockets aus, tauchen keine Exceptions mehr auf aber dafür ein deftiges Speicherleck. Also muss dies doch mit delete freigegeben werden weil anscheinend nach Zerstörung der Klasseninstanz noch Reste des Sockets im Speicher übrig bleiben. Hat jemand nen heissen Tip?



  • Kannst du dir den Stack Trace beim Auftreten der Exception angucken?



  • 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;
    
    }
    //--------------------------------------------------------------------------------------------------------
    

Anmelden zum Antworten