Einzelnen Beitrag anzeigen

Muetze1
(Gast)

n/a Beiträge
 
#7

Re: Server disconnectet Client

  Alt 26. Dez 2004, 18:44
Moin!

Richtig, beim ClientConnect gibt es noch keine Kommunikation und der Client kann daher nur danach seinen Nick schicken. Daher musst du das nachträglich zuordnen. Erstmal aber nochwas zwischendurch: Die ListBox speichert nicht die Sockets - sie hält auch einen Verweis auf diese Instanzen. Der ServerSocket verwaltet und hält diese hauptsächlich. Daher kannst du z.B. auch weiterhin die Connections[] des ServerSockets durchgehen um den Nickname zu zu ordnen. Andere Möglichkeit: Du baust dir ein Objekt - besser eine kleine Klasse - die nix weiter enthält als 2 Variablen im Public Bereich:

Delphi-Quellcode:
  TUserSocket = Class
  Public
    Socket : TCustomWinSocket;
    NickName : String;
  End;
Und wenn du nun bei der ListBox einfach anstatt dem Socket folgendes hinzufügst:

Delphi-Quellcode:
Procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
Var
  lTemp : String;
  lUser : TUserSocket;
Begin
  Memo1.Lines.Add(timetostr(now)+' Neuer User betritt den Chat !');
  edit10.text := 'User eingeloggt: ' + IntToStr(ServerSocket1.Socket.ActiveConnections);

  lUser := TUserSocket.Create;
  lUser.Socket := Socket;
  lUser.NickName := ''; // noch unbekannt, sind ja im Connect...

  lTemp := Socket.RemoteHost + ' ' + Socket.RemoteAddress;
  ListBox1.Items.AddObject(lTemp, lUser);
End;
Somit haben wir es nun so, das wir nicht mehr direkt den Socket reinhängen sondern diese Instanz von TUserSocket die uns beide nötigen Informationen hält: Den Socket und den Nick. Nun fehlt noch die Zuordnung vom Nick:

Delphi-Quellcode:
  // Diese Funktion geht nur durch die ListBox durch und sucht den TUserSocket zu dem übergebenen Socket
Function TForm1.FindUserSocket(ASocket : TCustomWinSocket): TUserSocket;
Var
  i : Integer;
Begin
  Result := Nil;

  For i := 0 To ListBox1.Items.Count-1 Do
    If ( TUserSocket(ListBox1.Items.Objects[i]).Socket = ASocket ) Then
    Begin
      Result := TUserSocket(ListBox1.Items.Objects[i]);
      Break;
    End;
End;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  lUser : TUserSocket;
  lText : string;
begin
  lText := Socket.ReceiveText;

  lUser := FindUserSocket( Socket );
  
  If ( Assigned(lUser) ) Then
  Begin
    lText := xorstring(lText, '');
    lUser.NickName := Copy(lText, 1, 6);

    ShowMessage(lUser.NickName);
  End;
End;
Nun enthält die TUserSocket in der ListBox auch den Nickname, wenn der denn ankommt.

Dadurch, das in der ListBox nun eine Instanz von TUserObject hängt die wir selber instanziiert haben, müssen wir uns um die Freigabe kümmern und natürlich die anderen Routinen abhändern.

Delphi-Quellcode:
Procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
Var
  i : Integer;
  lUser : TUserSocket;
Begin
    // Socket ist eindeutig, daher haben wir durch das Connect schon diesen Socket auch in der ListBox.
    // Also: ListBox1.Items.Objects[] durchgehen, schauen wo dieser übergebene Socket ist und dann den
    // Eintrag löschen. Fertig!

  Memo1.Lines.Add(timetostr(now)+' User verlässt den Chat !');
  edit10.text := 'User eingeloggt: ' + IntToStr(ServerSocket1.Socket.ActiveConnections-1); // noch ist ActiveConnections nicht aktuell!

  lUser := FindUserSocket( Socket );

  If ( Assigned(lUser) ) Then
  Begin
    For i := 0 To ListBox1.Items.Count-1 Do
    Begin
      If ( ListBox1.Items.Objects[i] = lUser ) Then
      Begin
        ListBox1.Items.Delete(i);
        Break;
      End;
    End;

    lUser.Free;
  End;
End;

Procedure TForm1.Button1Click(Sender: TObject);
Var
  lUser : TUserSocket;
Begin
    // wenn ein Eintrag ausgewählt ist...
  If ( ListBox1.ItemIndex > -1 ) Then
  Begin
      // dann den mit AddObject() hinzugefügten TUserSocket mal rausholen
    lUser := ListBox1.Items.Objects[ ListBox1.ItemIndex ] As TUserSocket;

    ShowMessage(lUser.NickName + ' wurde gekickt');

      // ... und dann einfach den Socket schliessen
    lUser.Socket.Close;
  End;
End;
Zu den ClientSocket/ServerSocket als Chat mit Nicks, Channels, etc siehe für Ideen und Hinweise auch den (bisher noch unkommentierten) Code von mir an: Chat Beispiel.

MfG
Muetze1
  Mit Zitat antworten Zitat