![]() |
TServerSocket OnClientRead - Client # identifzieren
Hallo,
ich bin mal wieder dabei mit delphi herumzuspielen. Im moment versuche ich mich an einer server/client struktur. Ich benutze TServerSocket und TClientServer. Soweit funktioniert alles ganz gut. Kleine Frage kommt aber auf. Wenn an einen server mehrere clients (sagen wir 3) connected sind und der server etwas empfängt und mit OnClientRead abgearbeitet wird... Gibt es eine kleine, feine server-side möglichkeit zu identifzieren welcher client (1, 2 oder 3) das paket geschickt hat? Fiktives Beispiel:
Delphi-Quellcode:
Irgendwo/wie hat delphi die connection doch gespeichert für sachen wie:
...
procedure TForm1.ServerSocketClientRead(Sender: TObject; Socket: TCustomWinSocket); var MSG: TChatMSG; var i:integer; begin If MSG.Text='disconnect me!' then begin i:=SocketNumber; // <-- SocketNumber ist hier der fiktive wert/befehl den ich suche ServerSocket.Socket.Disconnect(i); end else { hier käme behandlung von text wenn nicht disconnect me! } end; ... ServerSocket.Socket.Connections[x] ServerSocket.Socket.Disconnect(x) wobei ich eben nach dem rückwertsweg suche. also wie kriege ich x heraus? Anmerkung: ich könnte mir vorstellen workarounds zu benutzen: - ein array mit # und ip erstellen und bei jedem OnClientRead die IP mit dem array vergleichen und bei treffer i setzen. Nachteil: CPU intensiv wenn die clientzahl steigt und das array muss immer aktuallisiert werden wenn ein neuer client (dis)connected... - jedem client eine id zuweisen und sie ihm senden und jedesmal mit an den server senden. Nachteil: overhead und man könnte es exploiten und einen anderen client disconnecten lassen... Nur wie gesagt, wenn es ohne diese workarounds geht entschuldigt dass ich nicht von alleine drauf komme (oder ein tutorial/beispiel finde) und fragen muss. Edit: ich hab irgendwoanders etwas von TSocketNotifyEvent gelesen mit dem das anscheinend gehen soll. leider komm ich nicht drauf wie ich das benutzen soll bzw auf die connection# komme. Danke im Vorraus Catwiesel |
Re: TServerSocket OnClientRead - Client # identifzieren
TSocketNotifyEvent ist die Routine, welche du oben gerade implementierst. Das kennzeichnende daran sind die 2 Übergabeparameter. Zum einen Sender: ist hier nicht von Interesse. Zum anderen "Socket": Das ist genau das Socket, dass dir geschrieben hat und an welches du antworten musst/kannst.
Du kannst jetzt natürlich noch etwas probieren:
Delphi-Quellcode:
aber du wirst feststellen, dass es quatsch ist, erst die Nummer rauszusuchen um dann gleich wieder aus der Nummer das entsprechende Socket zu bestimmen.
for x:=0 to ServerSocket.SocketCount-1 do
if ServerSocket.Socket[x]=Socket then Socketnumber:=x; |
Re: TServerSocket OnClientRead - Client # identifzieren
Danke.
Muss aber dennoch nochmal genau nachfragen. Leider komme ich gerade nicht an delphi ran und kanns nicht selber probieren... Ich vermute ich kann nicht einfach i:=socket setzen und dann in i die zahl zu haben deren client mir eben gesendet hat. Oder doch? Du implizierst es ein wenig in deiner antwort. Ich verstehe deine schleife und bin dankbar, es wäre eine lösung. aber sozusagen nur eine notlösung eben weil eine schleife durchläuft und bei steigender client zahl cpu leistung frisst... du implizierst auch dass die schleife blödsinn wäre. aber wie setze ich dann i auf die nummer deren client mir eben was gesendet hat? danke im vorraus Catwiesel edit: ich hab nun socket versucht, ging natürlich nich. ich hab auch deine schleife versucht, und ich versteh nich ganz, aber sie geht auch nicht. anscheinend kennt er socketcount nicht? habe dann ActiveConnections genommen, aber dann stockt er bei ServerSocket.Socket[i]=Socket |
Re: TServerSocket OnClientRead - Client # identifzieren
Wieso willst Du überhaupt den Index haben? Falls Du über den Index in einem anderen Array irgendwelche Daten ablegen willst, dann verwende lieber die 'Data'-Eigenschaft des Sockets.
Delphi-Quellcode:
procedure TfmMain.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket); begin Socket.Data := TUserData.Create; end; procedure TfmMain.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin TUserData(Socket.Data).Free; end; procedure TfmMain.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket); begin With TUserData(Socket.data) do // ja ja, with ist pöse end; |
Re: TServerSocket OnClientRead - Client # identifzieren
hmm, wieso will ich den index haben? aus verschiedenen gründen. hauptsächlich weil ich bei incomming connections wissen von welchem client die nachricht kommt ohne alle ActiveConnections in einer Schleife abzuklappern und die RemoteIP mit einem array zu vergleichen um auf den index zu kommen - oder den clients immer die aktuelle index zahl zu geben, die clients jedesmal mitschicken zu lassen und zu aktuallisieren bei jedem disconnect.
vielen dank auch für deinen vorschlag mit der data eigenschaft des sockets. ich werde damit mal herumspielen und schauen ob es für meine zwecke reicht. wenn aber vielleicht doch noch jemand eine property kennt die mir einfach (mehr oder weniger) einen integer wert liefert der der connection# entspricht dass man folgendes tun könnte wäre ich sehr dankbar: ServerSocket.Socket.Disconnect(connection#); |
Re: TServerSocket OnClientRead - Client # identifzieren
Vielleicht passt Du dein Konzept einfach dem 'as-is' an.
So ein Socket kennt doch seine IP-Adresse. Wie gesagt, 'welcher' Client dich gerade angerufen hat, sagt die Socket-Instanz aus. Ein und der selbe Client wird immer den gleichen Socket verwenden, also könntest Du eine ClientID aus 'Integer(Socket)' erstellen. Oder eben du klebst -wie in meinem Beispiel- die Clientdaten gleich an die Data-Eigenschaft. Denn dazu ist sie doch da. Einen Index kannst Du auch so vergeben, aber wozu, versteh ich immer noch nicht:
Delphi-Quellcode:
Du brauchst nicht wirklich einen Index....
procedure TfmMain.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket); begin Socket.Data := Integer (ErsterFreierIndexInMeinemArray); MeinArray[integer(Socket.Data)] := irgendwas; end; procedure TfmMain.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin MeinArray [Integer(Socket.Data)] := 0; end; procedure TfmMain.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket); Var SocketIndex : Integer; begin SocketIndex := Integer (Socket.Data); end; Mir fällt gerade ein, du könntest einen brauchen, wenn du die Clients in einer Tabelle (TStringGrid o.ä.) darstellen willst. Dann merkst Du dir den Index einfach in deinen TUserDaten, die Du an die 'Data'-Eigenschaft gepeppt hast, so ähnlich, wie in dem 2.Beispiel. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz