Einzelnen Beitrag anzeigen

Benutzerbild von Cyberaxx
Cyberaxx

Registriert seit: 15. Jul 2005
311 Beiträge
 
Delphi XE5 Professional
 
#7

Re: Abfragen ob eine Variable oder die Referenz noch existie

  Alt 25. Sep 2007, 10:11
AClient ist in dem Fall nur ein Item aus einer Collection.

Wenn ich sie auf nil setze müsste sie doch auch nachdem der Socket getrennt wurde noch vorhanden sein oder verstehe ich das da etwas falsch?

Delphi-Quellcode:
procedure TDC_SPA.FSocketClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
  var
    Index: Integer;
    AClient: TClient;
    DCFrame: String;
begin
  if FClients.FindSocket(Socket, Index) then begin
    AClient := FClients.Client[Index];

    AClient.Buffer := AClient.Buffer + Socket.ReceiveText;

    AClient.Buffer := StringReplace(AClient.Buffer, #$d#$a, LineFeed, [rfReplaceAll]);


    if AClient.Buffer > 'then begin
      while (Pos(EOCommand, AClient.Buffer) > 0) do begin
        Index := Pos(EOCommand, AClient.Buffer);
        DCFrame := Copy(AClient.Buffer, 1, Index + 4); // +4 ersetzten durch Length(EOCommand)
        AClient.Buffer := Copy(AClient.Buffer, Index + 5, Length(AClient.Buffer)); // +5 ersetzen

        Parse_DCFrame(AClient, DCFrame);

        if not Assigned(AClient) then
          Exit;

        if AClient.Buffer = 'then
          Exit;

        if AClient.SID = 0 then
          Exit;
        end;

      end;
    end;

end;

procedure TDC_SPA.Parse_DCFrame(AClient: TClient; AFrame: String);
  var
    Framelist: TFramelist;
    Command: Integer;
    AUser: TUser;
    Index: Integer;
begin
  if Assigned(FOnRawData) then
    FOnRawData(Self, rsIn, AClient.SID, AFrame);

  [...]

  case Command of // Kommandoframe auswerten
    CMD_AUTH: HandleLogin(AClient, Framelist); // Anmelden
    CMD_PONG: HandlePong(AClient, Framelist); // Pong
    CMD_SEND_USER: HandleUserMessage(AClient, FrameList); // Nachricht an einen Benutzer

    // Alle Commands > 100 werden extern gehandled;
    else begin
    // Sicherstellen das das Command über 100 liegt
      if Command < 100 then
        Exit;

      // Nur wenn der Socket einem Benutzer zugeordnet werden kann fortfahren
      if Users.FindSocket(AClient.Socket, Index) then
        AUser := Users.User[Index]
          else Exit;

      // Übergabe an Extern
      if Assigned(FOnCommand) then
        FOnCommand(Self, AUser, Command, Framelist);
      end;
  end;

  Framelist.Free;
end;

procedure TDC_SPA.HandleLogin(AClient: TClient; FrameList: TFrameList);
  var
    Index: Integer;
    AUser: TUser;
    AuthVal: Boolean;
begin
  if Framelist.Count <> 6 then // Anzuahl der Frames MUSS 6 sein
    begin
    SendMessage(AClient.Socket, CMD_LOGIN_FAIL, 'Login Error. Not enough parameters'); // Fehlermeldung falls ungültig
    AClient.Socket.Close; // Socket freigeben
    Exit;
    end;

  if Not Users.FindUser( FrameList.Frames[1].Frame, Index ) then begin
    AUser := FUsers.AddConnection(AClient.Socket);
    AUser.SID := AClient.SID;
    AUser.LoginTime := Now;
    AUser.LPStamp := TimeStamp;
    AUser.Address := FrameList.Frames[3].Frame;
    AUser.User := FrameList.Frames[1].Frame;
    AUser.Name := FrameList.Frames[2].Frame;
    AUser.Pass := Framelist.Frames[4].Frame;

    if Assigned(FAuthData) then
      FAuthData(Self, AUser, AuthVal)
        else AuthVal := True;

    AUser.Authed := AuthVal;

    if AuthVal then begin
      SendMessage(AUser.Socket, CMD_LOGIN_OK, 'Logged on');

      SendUserlist(AUser, ucsLogin);

      if Assigned(FConnectionsStatus) then
        FConnectionsStatus(Self, FClients.Count, FUsers.Count);
      end
        else begin
        SendMessage(AUser.Socket, CMD_LOGIN_FAIL, 'Login Disabled');
        AUser.Socket.Close; // Verbindung trennen
        end;
    end
      else begin
      SendMessage(AClient.Socket, CMD_USER_IN_USE, 'User allready connected'); // Benutzer bereits verbunden
      AClient.Socket.Close; // Verbindung trennen
      end;
end;

procedure TDC_SPA.FSocketClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
  var
    Index: Integer;
    TmpUser: TUser;
    SID: Integer;
begin

  if FUsers.FindSocket(Socket, Index) then begin
    TmpUser := FUsers.User[Index];
    SID := TmpUser.SID;
    TmpUser.Free;
    end;

  if FClients.FindSocket(Socket, Index) then begin
    FClients.Client[Index].SID := 0; // Nutze ich nun zur Prüfung ob der Client noch vorhanden ist, damit gehts ohne Fehler
    FClients.Client[Index].Free; // <-- Hier wird das Item in dem Fall der Inhalt aus AClient freigegeben
    end;

  if Assigned(FConnectionsStatus) then
    FConnectionsStatus(Self, FClients.Count, FUsers.Count);

  // Clients über die veränderung benachrichtigen
end;
Klappt das ohne Probleme wenn ich das Item von FClients aus nil setze?
Daniel
Das Aufwachen aus einem boesen Traum muss einen nicht erleichtern. Es kann einen auch erst richtig gewahr werden lassen, was man Furchtbares getraeumt hat, vielleicht sogar welcher furchtbaren Wahrheit man im Traum begegnet ist!
  Mit Zitat antworten Zitat