Autor |
Beitrag |
Sithlord
      
Beiträge: 172
|
Verfasst: Mo 28.12.09 15:03
Hallo Mitglieder,
bin grad dabei ein kleines Server/Client Programm zu schreiben. Nun sendet z.b. ein Client einen Befehl zum Server, der diesen dann veranlagt, an einen bestimmten Clienten etwas zu senden. Von jedem angemeldeten Clienten habe ich die eindeutige IP Adresse in einer Listbox gespeichert.
Meine Frage:
Wie veranlasse ich den Server, nur an den einen Clienten einen Befehl zu schreiben - die anderen Clienten müssen aber verbunden bleiben.
Mfg Sithlord
Moderiert von Narses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.
|
|
Xentar
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: Mo 28.12.09 15:51
Du hast ne wichtige Info vergessen:
Mit welcher Komponente arbeitest du? Indy? Wenn ja, welche Version? Oder die normalen Server und ClientSocket ?
_________________ PROGRAMMER: A device for converting coffee into software.
|
|
Astat
      
Beiträge: 75
Erhaltene Danke: 1
Windows 2000
D6, D7, D2007, Lazarus
|
Verfasst: Mo 28.12.09 16:07
Sithlord hat folgendes geschrieben : | ..
Von jedem angemeldeten Clienten habe ich die eindeutige IP Adresse in einer Listbox gespeichert.
Meine Frage:
Wie veranlasse ich den Server, nur an den einen Clienten einen Befehl zu schreiben - die anderen Clienten müssen aber verbunden bleiben.
Mfg Sithlord |
Hallo Sithlord, den Client kannst Du immer durch den zugehörigen Socket identiffizieren. D.h. "Socket" ist für einen Client immer eindeutig.
Bei Verwendung einer IP, bekommst Du Probleme, wenn mehrere Netzwerkkarten, WLan, PPP-Adapter etc. aktiv sind, und die Ermittlung der IP somit nicht immer eindeutig ist.
Um dieses Problem zu beheben, speichere Dir in jedem Connect ein Object, bzw. Record etc. mit den übermittelten Clientinfos, eine GUID ist dafür gut geeignet, in einer schnellen Hash Liste. Bei jeder Anfrage eines Clients durchsuchst Du die Liste mit dem Socket als ID und bekommst dann das vorher gespeicherte Clientobject zurück.
An einen bestimmten Client kannst Du einfach mit dem Socket zurückschreiben.
Durchsuche die Hashliste nach deinen gewünschten Parametern (IP, Rechnername, MAC, Username etc.), ermittle den Socket, und Sende die Daten mit, send(Socket,..) bei Verwendung der Socket-API, oder bei Verwendung in Komponenten meist soetwas wie Socket.Send... an den Client.
Beschriebenes Szenario funktioniert natürlich nur wenn die Sockets permanent verbunden sind.
lg. Astat
Moderiert von Narses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.
|
|
Sithlord 
      
Beiträge: 172
|
Verfasst: Mo 28.12.09 16:50
So in etwa wollte ich das auch haben, super Idee,
es gibt nun noch ein problem: Was muss ich vom Socket den speichern lassen - damit der socket weiß an welchen Client er das schicken muss.
Oder wie veranlasse ich es, das der Socket das dann an den Clienten schreibt - muss ja bestimmt eine eindeutige Identifizierung irgendwo vorliegen...
Oh sehe es erst jetzt, die Tclient und Tserver - die stinknormalen VCL Socket komponenten von Delhpi7
|
|
Astat
      
Beiträge: 75
Erhaltene Danke: 1
Windows 2000
D6, D7, D2007, Lazarus
|
Verfasst: Mo 28.12.09 17:25
Sithlord hat folgendes geschrieben : | So in etwa wollte ich das auch haben, super Idee,
es gibt nun noch ein problem: Was muss ich vom Socket den speichern lassen - damit der socket weiß an welchen Client er das schicken muss.
Oder wie veranlasse ich es, das der Socket das dann an den Clienten schreibt - muss ja bestimmt eine eindeutige Identifizierung irgendwo vorliegen... |
Hallo Sithlord, ich gehe mal von einer Asynchronen Socketverbindung aus.
Du musst den Client-Socket, oder das ClientObject, bei Verwendung einer Komponente, speichern, den Du im Connect Event bekommst. Mit diesem Socket (Object) kannst Du dann zu jeder Zeit an einen Client Daten zurückschicken.
PS: Zeig mal den Source, dann kann gezielter geholfen werden.
lg. Astat
|
|
Sithlord 
      
Beiträge: 172
|
Verfasst: Mo 28.12.09 18:52
Hier, wollte das ein User dem anderen einen Text senden kann, der Code ist vom Server. Ich habe aber nicht gefunden was ich da speochern muss vom Sender:TObject ?
Mfg Sithlord
Hier mal der Code von der Komponente:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61:
| procedure TForm1.serverClientConnect(Sender: TObject; Socket: TCustomWinSocket); var remoteip:string; begin remoteip:= socket.RemoteAddress; sender. listbox1.Items.Add('Client '+remoteip+ ' verbunden'); end;
procedure TForm1.serverClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); var remoteip:string; i:integer; begin remoteip:=socket.RemoteAddress; listbox1.Items.Add('Client '+socket.RemoteAddress+' getrennt'); for i := 0 to Listbox2.items.count - 1 do begin if Pos(remoteip, ListBox2.Items[i]) > 0 then listbox2.Items.Delete(i); end; end; procedure TForm1.serverClientWrite(Sender: TObject; Socket: TCustomWinSocket); var received:string; received2:string; remoteip:string; A: TStringList; LABEL sendpong; LABEL sendtext; LABEL ende; begin A := TStringList.Create; received:=socket.ReceiveText; Split('|', received, A) ; received2:=A[0]; remoteip:=socket.RemoteAddress; listbox1.Items.Add('Befehl: '+received); if (received='ping') then GOTO sendpong else if (received='sendtext') then GOTO sendtext else GOTO ende; sendpong: listbox1.Items.Add('Ping von ' +remoteip+ ' bekommen'); socket.SendText('pong'); listbox1.Items.Add('Pong an ' +remoteip+ ' gesendet'); listbox1.Items.Add(remoteip+' ist nun angemeldet!'); listbox2.Items.Add(remoteip); GOTO ende; sendtext: GOTO ende; ende: A.Free; end; |
--- Moderiert von Narses: Beiträge zusammengefasst---
Im Prinzip ist es ja aufgebaut wie "flüstern" beim Chatten. Ich find bloß grad das Tutorial für einen Delphi Chat, worin man flüstern konnte, nicht mehr
Wäre sehr nett wenn den jemand auftreibt ^^
Edit:
Hab nun herausgefunden, es gibt dieses Socket.activeconnetions - wird verwendet um jeden Clienten was zu schicken, wenn ich jetzt wüsste, welcher Integer der grad neu verbundene Client hat - wäre alles perfekt gelöst
Mfg SIthlord
|
|
Astat
      
Beiträge: 75
Erhaltene Danke: 1
Windows 2000
D6, D7, D2007, Lazarus
|
Verfasst: Mo 28.12.09 23:12
Hallo Sithlord, anbei ein Demo wie das gemacht werden kann.
Bei dem Demo ist noch kein Empfanhsbuffer für jeden verbundenen Client, und auch noch kein Protokoll implementiert.
Solltest Du noch weitere Hilfe brauchen, einfach Melden.
lg. Astat
Einloggen, um Attachments anzusehen!
|
|
Sithlord 
      
Beiträge: 172
|
Verfasst: Mo 28.12.09 23:22
Vielen, vielen Dank
Aber ich steige da nicht so sehr ganz durch, sorry.
Mache dies ja alles nur Hobbymäßig und belese mich da schon ne Menge.
Ich hätte da auch noch einen Ansatz:
Es gibt ja bei diesen Komponenten dieses "Activeconnetions".
Demnach müsste jeder verbundene Client einen eindeutigen Integerwert haben.
Diesen würde ich in einer Listbox abspeichern und bei bedarf abrufen
Wie find ich diesen Wert raus?
Bsp:
Delphi-Quelltext 1: 2: 3:
| for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do ServerSocket1.Socket.Connections[i].SendText(MyMessage); |
Oder was ist eig. dieses Sockethandle - ist das auch bei jedem einzigartig oder
wie soll ich den Quelltext von dir verstehen?
Mfg Sithlord
|
|
Astat
      
Beiträge: 75
Erhaltene Danke: 1
Windows 2000
D6, D7, D2007, Lazarus
|
Verfasst: Di 29.12.09 00:46
Moderiert von Narses: Komplett-Zitat des letzten Beitrags entfernt.
Hallo Sithlord, ServerSocket1.Socket.Connections[i] liefert das TCustomWinSocket Object zurück.
ServerSocket1.Socket.Connections[i].SocketHandle liefert das "SocketAPI" Socket Handle.
Beide sind immer für einen Client eindeutig, wobei ein IntToStr(ServerSocket1.Socket.Connections[i].SocketHandle) am einfachsten zu handhaben ist.
Das Sockethandle habe ich nur verwendet um das zugehörige Clientobjekt in der Listbox zu suchen.
Im Hinterkopf hatte ich da eine spätere Object suche, nach einem Integer (Sockethandle), aus einer Hashlist.
Du kannst natürlich auch direkt das TCustomWinSocket Object verwenden.
lg. Astat
|
|
Sithlord 
      
Beiträge: 172
|
Verfasst: Di 29.12.09 01:29
Vielen Dank,
damit bleibt für mich nur noch als letzte Frage woher ich das i wissen kann - vl. stelle ich mich dabei auch doof an aber der erste Client bekomm ja 0, der zweite 1 usw. Aber was ist wenn der dritte geht - wird diese Lücke aufgefüllt oder nicht.
Mfg Sithlord
P.S. Vielen Dank für deine Hilfe, hast alle deine ersten Posts an meinem Problem verschwendet ^^
|
|
Astat
      
Beiträge: 75
Erhaltene Danke: 1
Windows 2000
D6, D7, D2007, Lazarus
|
Verfasst: Di 29.12.09 06:35
Moderiert von Narses: Komplett-Zitat des letzten Beitrags entfernt.
Hallo Sithlord, die Komponente aktualisiert automatisch die Interne Connection Liste. D.h. Wenn ein Disconnect und oder Socket Error ausgelöst wird, wird der Socket, der das verursacht, automatisch aus der Liste entfernt. Also die Lücke wird nicht ausgefüllt, sondern es wird diese entfernt. Alle nachfolgenden Einträge rücken nach, und bekommen somit um ActIndex -1, einen neuen index.
Beispiel: 1, 2, 3, 4, 5 sind vorhanden, dann wird 3 entfernt, somit werden alle > 3 um eins decrementiert 4 wird zu 3, 5 wird zu 4 usw.
Tip:
Auf Grund dieses Verhaltens, solltest Du die Schleife wo du Daten an die Client sendest, mit for i := LisBox1.items.count -1 downto 0 do .. aufbauen. Denn wenn währen des Sendens sich ein Client Disconnectet, kommt es nicht zu einer Indexverletzung.
lg. Astat
Moderiert von Narses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Sa 02.01.10 02:32
Moin!
Sithlord hat folgendes geschrieben : | Im Prinzip ist es ja aufgebaut wie "flüstern" beim Chatten. Ich find bloß grad das Tutorial für einen Delphi Chat, worin man flüstern konnte, nicht mehr
Wäre sehr nett wenn den jemand auftreibt |
Falls du das hier gemeint hast?
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Astat
      
Beiträge: 75
Erhaltene Danke: 1
Windows 2000
D6, D7, D2007, Lazarus
|
Verfasst: Sa 02.01.10 06:41
Narses
www.delphi-library.d...kets+v400_54269.html
Hallo Narses, muss schon sagen, Hut ab!! Ist eine wahnsinns Doku und Source!! Respekt!!
lg. Astat
|
|
|