AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Server disconnectet Client
Thema durchsuchen
Ansicht
Themen-Optionen

Server disconnectet Client

Ein Thema von PierreB · begonnen am 24. Dez 2004 · letzter Beitrag vom 30. Dez 2004
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    
PierreB
(Gast)

n/a Beiträge
 
#1

Server disconnectet Client

  Alt 24. Dez 2004, 09:22
hallo dp,

wiedermal ein socket-problem:

diesmal möchte ich vom server aus einzelne Clienten disconnecten.
beim connecten eines clienten werden die clienten-daten in ein listbox geladen:

Code:
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
 ib : integer;
begin
Memo1.Lines.Add(timetostr(now)+' Neuer User betritt den Chat !');
edit10.text := 'User eingeloggt: ' + IntToStr(ServerSocket1.Socket.ActiveConnections);
listbox1.Clear;
for ib := 0 to Serversocket1.Socket.ActiveConnections - 1 do
listbox1.Items.Add(serversocket1.Socket.Connections[ib].RemoteHost + ' ' + serversocket1.Socket.Connections[ib].remoteaddress);
end;
nun möchte ich das man ein item der listbox anklickt, dann auf den 'disconnect' button geht und die
verbindung zu diesem clienten getrennt wird.

oder eigentlich würde mir auch schon 'normaler' Code (ohne listbox) helfen.

bisher habe ich folgendes versucht:
Code:
procedure button1click;
begin
serversocket1.socket.connections[0].disconnect(1);
// oder das:
serversocket1.socket.connections[1].disconnect(1);
end;
beides funzt aber net !

die delphi hilfe konnte mir nicht helfen und aus google wurde ich auch net schlau !

Frohe Weihnachten !
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#2

Re: Server disconnectet Client

  Alt 24. Dez 2004, 21:50
Moin!

1. Warum löscht bei einem einzelnen Connect eines neuen Clients gleich die Listbox? Warum fügst du nicht einfach den Client der Listbox hinten an?

2. Warum nutzt du nicht die AddObject() Methode von TStrings und fügst den ServerSocket1ClientConnect() übergebenen Socket einfach mit an den Eintrag mit an? Dieser ist immer eindeutig zu der Connection.

3. Mit dem Vorschlag aus 2. wird es beim ServerSocket1ClientDisconnect() einfacher, weil du dann in dem Objects[] Array nachschauen kannst nach dem Socket der sich verabschiedet hat und somit nur noch den einen Eintrag löschen musst bei der ListBox

4. Und mit dem Vorschlag aus 2. wird deine eigentliche Frage (disconnecten eines gewählten Clients) auch einfach lösbar: Den Socket wieder aus dem Objects[] Array der ListBox rausholen, zu einem TCustomWinSocket casten und einfach seine Methdoe Close() aufrufen. Fertig ist die Suppe...

MfG
Muetze1
  Mit Zitat antworten Zitat
PierreB
(Gast)

n/a Beiträge
 
#3

Re: Server disconnectet Client

  Alt 25. Dez 2004, 20:23
Hallo,


Zitat:
1. Warum löscht bei einem einzelnen Connect eines neuen Clients gleich die Listbox? Warum fügst du nicht einfach den Client der Listbox hinten an?
das hatte ich versucht hat aber net geklappt ! Also lösche ich immer das listbox und schreibe dann alle
aktiven connections wieder rein ! (Not macht wohl erfinderisch !)
Zitat:
2. Warum nutzt du nicht die AddObject() Methode von TStrings und fügst den ServerSocket1ClientConnect() übergebenen Socket einfach mit an den Eintrag mit an? Dieser ist immer eindeutig zu der Connection.
weil ich nicht wusste das sowas geht ! kannst du mir das bitte genauer erklären ?
Zitat:
3. Mit dem Vorschlag aus 2. wird es beim ServerSocket1ClientDisconnect() einfacher, weil du dann in dem Objects[] Array nachschauen kannst nach dem Socket der sich verabschiedet hat und somit nur noch den einen Eintrag löschen musst bei der ListBox
das ist natürlich besser als meine methode !
Zitat:
4. Und mit dem Vorschlag aus 2. wird deine eigentliche Frage (disconnecten eines gewählten Clients) auch einfach lösbar: Den Socket wieder aus dem Objects[] Array der ListBox rausholen, zu einem TCustomWinSocket casten und einfach seine Methdoe Close() aufrufen. Fertig ist die Suppe...
wunderbar ! nur wie geht das ganze ?
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#4

Re: Server disconnectet Client

  Alt 25. Dez 2004, 22:14
Moin!

Zitat von Muetze1:
1. Warum löscht bei einem einzelnen Connect eines neuen Clients gleich die Listbox? Warum fügst du nicht einfach den Client der Listbox hinten an?

2. Warum nutzt du nicht die AddObject() Methode von TStrings und fügst den ServerSocket1ClientConnect() übergebenen Socket einfach mit an den Eintrag mit an? Dieser ist immer eindeutig zu der Connection.
Delphi-Quellcode:
Procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
Var
  lTemp : String;
Begin
  Memo1.Lines.Add(timetostr(now)+' Neuer User betritt den Chat !');
  edit10.text := 'User eingeloggt: ' + IntToStr(ServerSocket1.Socket.ActiveConnections);

    // die oben übergebene Instanz "Socket" ist der neu angelegte Socket der für diesen neuen Client
    // angelegt wurde bzw. dessen Connection verwaltet. Daher können wir von ihm direkt die benötigten
    // Informationen wie RemoteHost etc abfragen. Ich habe hier mal eine temporäre lokale Variable lTemp
    // angelegt für den String der in ListBox erscheint.
    // Beim AddObject() kannst du ein Object mit angeben was dann zu dem Eintrag mit verwaltet wird. Wenn
    // du also mit Delete einen Eintrag löscht, dann fliegt dieses gleich mit raus. Daher hast du immer
    // zu jedem Eintrag den Socket und kannst z.B. wenn der Nutzer einen Eintrag in der ListBox ausgewählt
    // hat auch direkt diesem Client was schicken - einfach aus ListBox1.Items.Objects[] das Objekt rausholen
    // und zu einem TCustomWinSocket typecasten.

  lTemp := Socket.RemoteHost + ' ' + Socket.RemoteAddress;
  ListBox1.Items.AddObject(lTemp, Socket);
End;
Zitat von Muetze1:
3. Mit dem Vorschlag aus 2. wird es beim ServerSocket1ClientDisconnect() einfacher, weil du dann in dem Objects[] Array nachschauen kannst nach dem Socket der sich verabschiedet hat und somit nur noch den einen Eintrag löschen musst bei der ListBox
Delphi-Quellcode:
Procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
Var
  i : Integer;
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!

  For i := 0 To ListBox1.Items.Count-1 Do
  Begin
    If ( ListBox1.Items.Objects[i] = Socket ) Then
    Begin
      ListBox1.Items.Delete(i);
      Break;
    End;
  End;
End;
Zitat von Muetze1:
4. Und mit dem Vorschlag aus 2. wird deine eigentliche Frage (disconnecten eines gewählten Clients) auch einfach lösbar: Den Socket wieder aus dem Objects[] Array der ListBox rausholen, zu einem TCustomWinSocket casten und einfach seine Methdoe Close() aufrufen. Fertig ist die Suppe...
Ich gehe jetzt mal davon aus, das du den Client rausschmeissen willst, den der Benutzer in der ListBox ausgewählt hat.

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

      // ... und dann einfach den Socket schliessen
    lSocket.Close;
  End;
End;
Voraussetzung für alle von mir hier dargelegten Posts ist es, dass MultiSelection ausgeschaltet ist bei der ListBox!

MfG
Muetze1
  Mit Zitat antworten Zitat
PierreB
(Gast)

n/a Beiträge
 
#5

Re: Server disconnectet Client

  Alt 25. Dez 2004, 22:18
Ich danke dir erstmal

Ich teste das morgen mal aus !
  Mit Zitat antworten Zitat
PierreB
(Gast)

n/a Beiträge
 
#6

Re: Server disconnectet Client

  Alt 26. Dez 2004, 12:43
hallo muetze1,

vielen dank für deine hilfe funzt alles wunderbar

warum bin ich da nicht selber drauf gekommen ?

jetzt hab ich nur ( ) noch ein problem:

da alle clienten dann in der listbox abgespeichert werden, steht da ja der host und die ip.
wenn nun aber mehrere clienten eingeloggt sind, weiß ich dann nicht mehr welcher listbox-eintrag
(also ip + host) nun zu welchem user gehört !

deshalb habe ich versucht den nicknamen mit in die listbox zu speichern:
Im ClientConnect steht:
Code:
 ClientSocket1.Socket.SendText(xorstring(nachricht, ''));
Nachricht setzt sich aus dem Nicknamen (den der User eingibt) und 'hat den Raum betreten' zusammen.
Da der Nickname eh nur 6 Zeichen haben darf, hab ich ihn wie folgt ausgelesen:
Code:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
   Texta, encode : string;
begin
texta := Socket.ReceiveText;
nick := xorstring(texta, '');
nick:=Copy(nick, 1, 6);
showmessage(nick);
end;
nun hab ich zwar den nicknamen im serverprogramm, doch wie bekomm ich den nun zu dem entsprechenden
host + ip eintrag in die listbox ?? hab schon versucht das mit bei OnClientConnect einzubauen,
aber da ClientRead ja erst nach OnClientConnect ausgeführt wird, funzt das net !
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#7

Re: Server disconnectet Client

  Alt 26. Dez 2004, 17: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
PierreB
(Gast)

n/a Beiträge
 
#8

Re: Server disconnectet Client

  Alt 27. Dez 2004, 12:22


Code:
TUserSocket = Class
bin ich blöd ? Das muss doch bei type rein, oder ?
da kommt fehlermeldung:
Zitat:
Typ TUserSocket ist nicht vollständig definiert.
  Mit Zitat antworten Zitat
Benutzerbild von Pseudemys Nelsoni
Pseudemys Nelsoni

Registriert seit: 24. Dez 2002
Ort: Hamburg-Harburg
3.551 Beiträge
 
#9

Re: Server disconnectet Client

  Alt 27. Dez 2004, 12:27
das was du da hast ist eine vorwärtsdeklaration... du musst die klasse auch noch irgendwo "richtig" deklarieren (die abschnitte/methoden/felder der klasse etc)
Mario
MSN: cyanide@ccode.de
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#10

Re: Server disconnectet Client

  Alt 27. Dez 2004, 13:10
Moin!

Zitat von delphman:


Code:
TUserSocket = Class
bin ich blöd ? Das muss doch bei type rein, oder ?
da kommt fehlermeldung:
Zitat:
Typ TUserSocket ist nicht vollständig definiert.
Ich bin davon ausgegangen das dieses zu erkennen kein Problem wäre. Du hast es doch auch ordentlich erkannt, daher: warum dieser Post? Was anderes kanns nich sein, auch keine forward declaration, weil die Definition der Klasse direkt folgt...

Natürlich heisst es so
Delphi-Quellcode:
Type
  TUserSocket = Class
  Public
    Socket : TCustomWinSocket;
    NickName : String;
  End;


MfG
Muetze1
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz