Einzelnen Beitrag anzeigen

Nakaron

Registriert seit: 19. Mär 2004
28 Beiträge
 
Delphi 2007 Professional
 
#1

IdTCPServer Threadproblem

  Alt 24. Aug 2007, 12:38
Hallo zusammen,

ich bin gerade dabei eine Client->Server->Client Anwendung zuschreiben. Mein großes Problem ist dabei, sobald ein Client sich einmal mit dem Server verbunden hat und dann wieder disconnected und ich den Server beenden möchte, dass diese Serveranwendung einfriert und ich diese nur noch über den Taskmanager beenden kann.

Meine Einzige Vermutung liegt nun darin, dass die ThreadConnections nicht ordentlich geschlossen werden.
Anbei mal die wichtigsten Codesnippets aus meinem Projekt:

Delphi-Quellcode:
type
  PClient = ^TClient;
  TClient = record // Objekt enthält Daten vom Client
                IP : String[15]; { IP Adressse des Users }
                UserID : String[10]; { Benutzer ID in der DB }
                UserName : String[100]; { Benutzername }
                Connected : TDateTime; { Zeitstempel des Verbindungsaufbaus }
                Thread : Pointer; { Pointer zum IdContext-Thread }
              end;
.
.
.

var
  frmMain : TfrmMain;
  Clients : TThreadList;
.
.
.

procedure TfrmMain.TCPServerConnect(AContext: TIdContext);
var
  NewClient: PClient;
begin
  GetMem(NewClient, SizeOf(TClient));

  NewClient.IP := AContext.Connection.Socket.Binding.PeerIP;
  NewClient.Connected := Now;
  NewClient.Thread := AContext;

  AContext.Data:=TObject(NewClient);

  try
    Clients.LockList.Add(NewClient);
  finally
    Clients.UnlockList;
  end;
end;

procedure TfrmMain.TCPServerDisconnect(AContext: TIdContext);
var
  ActClient: PClient;
  vI : Integer;
begin
  ActClient := PClient(AContext.Data);
  try
    Clients.LockList.Remove(ActClient);
    for vI:=0 to lvConnectedClients.Items.Count-1 do
      if(PClient(lvConnectedClients.Items[vI].Data)^.IP = ActClient.IP) then
      begin
        Dispose(lvConnectedClients.Items[vI].Data);
        lvConnectedClients.Items[vI].Delete;
      end;
    grpConnectedClients.Caption := 'Angemeldete Clients (' + IntToStr(lvConnectedClients.Items.Count) + ' Benutzer)';
  finally
    Clients.UnlockList;
  end;

  FreeMem(ActClient);
  AContext.Data := nil;
end;

procedure TfrmMain.TCPServerExecute(AContext: TIdContext);
var
  Data: String;
  vI: Integer;
  ActClient : PClient;
begin
  Data := AContext.Connection.Socket.ReadLn;
  Data := decodeStr(Data);

  ActClient := PClient(AContext.Data);

  if(Pos('[CMClient]AuthMe', Data) > 0) then
  begin
    addToLog('Authentifizierungsanfrage von: ' + AContext.Binding.PeerIP, 0, [], 8);
    doSELECT('SELECT usr_id, usr_loginName FROM cm_user WHERE usr_loginName = "' + GetTagData('Username', Data) + '" AND usr_loginPassword = "' + GetTagData('Password', Data) + '" LIMIT 1');

    if(Query.RecordCount <> 0) then
    begin
      addToLog('Authentifizierung erfolgreich.', 15, [], 8, clGreen);
      ActClient.UserID := Query.FieldByName('usr_id').AsString;
      ActClient.UserName:= Query.FieldByName('usr_loginName').AsString;
      lvConnectedClients.AddItem(Query.FieldByName('usr_loginName').AsString, Pointer(ActClient));
      lvConnectedClients.Items[lvConnectedClients.Items.Count-1].SubItems.Add('');

      AContext.Connection.Socket.WriteLn(encodeStr('[CMServer]Verify<Reason>Success</Reason>'));
    end else
    begin
      addToLog('Authentifizierung fehlgeschlagen.', 15, [], 8, clRed);
      AContext.Connection.Socket.WriteLn(encodeStr('[CMServer]Verify<Reason>Failed</Reason><ErrorMsg>Falsche Benutzer/Passwort Kombination!</ErrorMsg>'));
    end;
    exit;
  end;
end;
Ich bin bereits seit Tagen auf der Suche nach einer Lösung. Ich hoffe ihr könnt mir weiterhelfen.

Vielen Dank schon einmal im voraus.

Viele Grüße
Nakaron
Andreas
  Mit Zitat antworten Zitat