AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi SocketServer & mehrere Clients verwalten
Thema durchsuchen
Ansicht
Themen-Optionen

SocketServer & mehrere Clients verwalten

Ein Thema von Cyberaxx · begonnen am 16. Aug 2005 · letzter Beitrag vom 20. Aug 2005
Antwort Antwort
Benutzerbild von Cyberaxx
Cyberaxx

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

SocketServer & mehrere Clients verwalten

  Alt 16. Aug 2005, 10:59
Hallo,

habe ein hoffentlich kleines nur Problemchen.

Ich nutze einen SocketServer und mehrere Clients. Die Client <-> Server Verbindung steht und Funktioniert prächtig.
Was mir jetzt fehlt ist über den Server eine Client <- Server -> Client Verbindung.
Wie ich eine Nachricht an den jenigen schicke der grad eine Anfrage an den Server stellt ist auch kein Problem,
nur wie bekomme ich den Server dazu das er dann von da aus die Nachricht an Client 'X' weiterleiten soll.
Die Clients kann ich alle per Protokoll identifizieren, z.B. wird dabei immer der PC-Name mit gesendet,
zusätzlich habe ich noch die IP. Aber ich weiss nicht wie ich herausbekomme Client 'X' direkt anzusprechen.

Hatte mir überlegt ich schicke es an jeden Client und verarbeite es da, nach dem Motto

IF PC-Name = MyOwn THEN... Doch wenn dann mal so 50 Rechner angemeldet sind, kommt da bei jedem schon ungehäuer Traffic auf,
der nicht wirklich sein müsste. Hatte auch schon gedacht über

Socket.Connections[n] aber selbst
da muss man bei 50 Rechnern wenn jemand die Verbindung trennt die ID's neu belegen, bis zu dem der trennte.

Gibt es eine Lösung womit ich wirklich nur das nötigste an Traffic verursache eben genau die vom
Server <-> Client und ohne das ich manuell eine riesen ID-Struktur selber anlegen müsste?

Sitze hier schon länger dran und komm nicht auf einen grünen Zweig...

Gruss Cyb
Daniel
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#2

Re: SocketServer & mehrere Clients verwalten

  Alt 16. Aug 2005, 11:15
Hallo Cyberaxx,

für eine bidirektionale Kommunikation musst du in deinem Programm beide Komponenten betreiben - SocketServer und SocketClient.

Grüße vom marabu
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#3

Re: SocketServer & mehrere Clients verwalten

  Alt 16. Aug 2005, 11:26
Ich habe mir dafür eine Klasse geschrieben, sodass die Apps mit Hilfe von mailslots kommunizieren können.
Wenn deine Clients und der Server in einer Domäne hängen, klappt das wunderbar, bei einer Arbeitsgruppe weiss ich es nicht.

Auf meinen Clients habe ich einen mailslot namens 'Rcv' eingerichtet. Ein thread setzt sich drauf und wartet, bis eine Nachricht eingetroffen ist (max 1k), dann wird ein Event abgefeuert. Man kann die mailslots auch pollen, also schauen, ob und wie gross die nachricht ist, dann einen Buffer aufmachen und die Daten dann abholen.

Wenn ich nun zum PC 'FooBar' eine Nachricht schicken will, dann schreibe ich die einfach an:'\\FooBar\.\mailslots\Rcv' und -bups- purzelt sie auf der anderen Seite raus.
Delphi-Quellcode:
///////////////////////////////////////////////////////////////////////////////
// SendMail: Send a Mail 'aMessage' to the Mailslot 'aSlotName' on the //
// Machine 'aComputer' //
///////////////////////////////////////////////////////////////////////////////
Procedure SendMail (aComputer, aSlotName, aMessage : String);
var
  Bytes: DWord;
  aPath : String;
  aHandle : THandle;

begin
  aPath := '\\' + aComputer + '\mailslot\' + aSlotName;
  aHandle := CreateFile(PChar(aPath), GENERIC_WRITE, FILE_SHARE_READ, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  try
    if aHandle = INVALID_HANDLE_VALUE then
      Raise EInOutError.CreateFmt('Cannot create mailslot %s\%s',[aComputer,aSlotName])
    else
      If not WriteFile(aHandle, Pointer(aMessage)^, Length(aMessage), Bytes, nil)
   Then Raise EInOutError.CreateFmt('Cannot write to mailslot %s\%s',[aComputer,aSlotName]);
  finally
    if aHandle <> INVALID_HANDLE_VALUE Then
      CloseHandle(aHandle);
    end;
end;
Hier ist der MailReceiver, also ein Thread, der auf eine mail wartet:
Delphi-Quellcode:
///////////////////////////////////////////////////////////////////////////////
// Object : TMailReceiver //
///////////////////////////////////////////////////////////////////////////////
constructor TMailReceiver.Create(aSlotName : String; aMaxLength : Integer);
Var
  aPath : String;

begin
  Inherited Create (True);
  fSlotName := aSlotName;
  fMaxLength := aMaxLength;
  aPath := '\\.\mailslot\' + aSlotName;
  fHandle := CreateMailSlot(PChar(aPath), 0, MAILSLOT_WAIT_FOREVER, nil);
  if fHandle = INVALID_HANDLE_VALUE Then //
    Raise Exception.Create ('Could not create mailslot, slotname already exists');
end;

destructor TMailReceiver.Destroy;
begin
  Terminate;
  CloseHandle (fHandle);
end;

procedure TMailReceiver.DoOnMailReceived;
begin
Try
  if Assigned (fOnMail) And (Length (fMessage)>0 ) Then
    fOnMail (Self, fMessage);
  Except
    End;
end;

procedure TMailReceiver.Execute;
Var
  aSize : DWord;

begin
  While Not Terminated Do Begin
    SetLength (fMessage, fMaxLength);
    if ReadFile(fHandle, PChar(fMessage)^, fMaxLength, aSize, nil) Then
      If not terminated Then
   SetLength (fMessage, aSize);
    if not terminated then
      Synchronize (DoOnMailReceived);
    End
end;

procedure TMailReceiver.Start;
begin
  Resume;
end;

procedure TMailReceiver.Stop;
begin
  Try
    Terminate;
    SetMailslotInfo (fHandle,0);
  Except
    End;
end;
Ach, wenn man als Empfänger ein '*' einträgt, dann wird die Mail an alle PC geschickt (also ein Broadcast).

Du erzeugst den TMailReceiver und startest den mit 'Start' (logisch), z.B. im FormCreate oder DatamoduleCreate.
Im flxrmgfDestroy stoppst du den TMailReceiver und schmeisst in Free technisch weg.

Du kannst natürlich mehrere Mailslots einrichten, sodass Du verschiedene Subsysteme realisieren kannst. Usw.

Das geht natürlich alles bestimmt viel eleganter (per UDP?), aber das ist mir alles zu blöd gewesen. so ist es simpel, überschaubar und funzen tut es auch
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von Cyberaxx
Cyberaxx

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

Re: SocketServer & mehrere Clients verwalten

  Alt 16. Aug 2005, 11:43
@Marabu
Wieso muss ich das?

Es ist beabsichtigt das es immer über den Server geht. Der Server übernimmt praktisch die ganze Verwaltungsarbeit.
Es geht ja auch das über den Server mehrere Clients auch untereinander komunizieren können ich will nur nicht den Weg des größten Traffics oder der ganzen adressiererei mit den ID's beim connecten und verlassen des Servers gehen.

Er soll jediglich dem Client PC0078 eine eindeutige ID geben mit der ich immer sagen kann, wenn jemand mit PC0078 reden will, das der Server weiss aha PC0078 hat ID = 1 also

Socket.Connections[1].SendText(S);
@Alzaimar
Klingt soweit nicht schlecht. Es soll sich hierbei aber nicht nur im eine 'chatartige' komunikation handeln, sondern später auch Dateien übertragen werden(Update Funktion von Programmen), da kann es dann auch mal zu einer grossen Datenmenge kommen.
Die Clients hängen auch leider nicht alle an einer Domäne.

Klingt jetzt doof aber auf der Keramik hat man ja bekanntlich die besten Ideen...
Ich weiss auch nicht wieso ich da erst jetzt drauf komme aber ich werds jetzt mal einfügen, vllt. gibt es ja noch eine einfachere Methode, hoff ich...

Wenn eine Nachricht für für den Client 'X' auftaucht, starte ich einfach eine Schleife und lasse ihn suchen
Beim connecten wird der IP ein PC-Name zugeordnet, hier eben PC0078

Delphi-Quellcode:
FOR n := 0 to MaxConnections DO BEGIN
IF Socket.Connections[n].RemoteAddress = Client 'X' Adresse THEN ....
NEXT;
Problem dabei ist wenn mehrere Clients die Selbe IP nutzen gibt es schon Probleme.
Daniel
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#5

Re: SocketServer & mehrere Clients verwalten

  Alt 16. Aug 2005, 12:17
Ich habe mein mailkonzept auch nicht zum übertragen grösserer Datenmengen gedacht, sondern zur Kommunikation.
Du kannst doch dem Client, mit dem du dich mal 'ernsthaft' unterhalten willst, folgende Mail schicken:
Code:
REQUEST CONNECT
Host 192.168.123.001
Port 12345
Daraufhin baut der Empfänger einen Socket auf Port 12345 zur Adresse 192.168.123.001 auf und wartet auf weitere Instruktionen. Über ein geeignetes a) Mail-Format oder b) Übertragungsformat auf IP-Ebene verschickst du dann einfach Deine Daten. Anschließend wird der Socket wieder entfernt und fettich.

Ich habe das (Mail-)Konzept benutzt, um meinen Clients mitzuteilen, das sich wichtige (Kunden-)Daten auf dem Server verändert haben und sie doch bitteschön mal bei Gelegenheit ein Refresh ausführen sollen.

Wenn Du bidirektionale Kommunikation mit einem SocketServer haben willst, müssen deine Clients Connectionpoints implementieren, oder einfach alle paar Sekunden nachfragen, ob's denn eine Nachricht gibt ...

Du implementierst auf Serverseite zwei kleine Methoden:
Delphi-Quellcode:
Procedure SendMail (Const aSender, aRecipient, aText : String);
Function GetMail (aMyID : String; Var aSender, aText : String) : Boolean;
Mit SendMail schickst Du eine kleine Mail an irgendjemanden. Der Server puffert sie und übergibt sie an den Empfänger. Da kann dann wieder sowas drinstehen, wie:'Ey, mach mal ein Socket auf, ich hab was für Dich' oder so.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#6

Re: SocketServer & mehrere Clients verwalten

  Alt 16. Aug 2005, 12:28
Hallo,
guck dir mal das hier an:

IMT - Chat Open Source

Es werden alle verbundenen Clients in eine Liste aufgenommen und an ihrem Index in der Liste identifiziert. Im Prinzip wird bei jedem OnConnect oder OnDisconnect Ereigniss die ActiveConnections Liste in einer Schleife abgearbeitet. In dieser Schleife sendet der Server einen Anfrage String erst an Client ID 0. Wenn Client 0 auf die Anfrage geantwortet hat, wird er in die Liste mit Computernamen, etc eingetragen und die Schleife wird fortgeführt.

Florian
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von Cyberaxx
Cyberaxx

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

Re: SocketServer & mehrere Clients verwalten

  Alt 16. Aug 2005, 13:50
Werd ich mir gleich mal ansehen. Bin jetzt gerade dabei zu versuchen es über den SocketHandel zu regeln, zumindest versuch ich es.
Es ist alles recht umständlich da auch ich immer wieder die Liste der Connections durchgehen muss.
Daniel
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#8

Re: SocketServer & mehrere Clients verwalten

  Alt 20. Aug 2005, 11:52
Da viele das selbe Problem wie du haben, habe ich diese Komponente entwickelt.

Florian
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Antwort Antwort


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 09:05 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