Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi TSocket - Online Spiel Kommunikation (https://www.delphipraxis.net/167220-tsocket-online-spiel-kommunikation.html)

mamble 18. Mär 2012 20:43

TSocket - Online Spiel Kommunikation
 
Hallo zusammen,

ich will ein Delphi-Spiel soweit programmieren das ein MultiplayerModus möglich ist.
Da ich mir das anfangs nicht zugetraut hatte und auch nicht wrkl. wusste wie ich das realisieren sollte habe ich erstmal ein kleines Boxspiel programmiert und dann versucht die Kommunikation zwischen zwei Spielern (und einem Server) per TSocket zu realisieren. Was besseres ist mir nicht eingefallen, ich weiß nicht was man sonst für einen OnlineModus nehmen könnte. ^^

Das läuft grob so ab:
Clientapp sendet Befehl an Serverapp, Serverapp sendet Befehl an Clients und Clients führen aus.

Das alles klappt jedenfalls auch soweit.... das Problem ist nur das die Kommunikation zwischen Client und Server relativ langsam ist... wenn ich beim Client beispielsweise per Mausklick ein mal "Schlage" dann kommt das an.

Wenn ich aber 10 mal extrem schnell draufklicke dann kommen meist weniger Schläge an... so ca. 5.

Habt ihr da einen Tipp?
Wie kann ich die Geschwindigkeit verbessern?
Liegts an meiner Leitung? (teste das alles Lokal)
Sollte ich was anderes als TSocket verwenden?
Oder realisiert man einen Onlinemodus überhaupt ganz anders?

Aphton 18. Mär 2012 21:29

AW: TSocket - Online Spiel Kommunikation
 
Windows puffert intern Daten, die geschickt werden. Dieser Puffer hat eine bestimmte Größe (kann man selber auch setzen; max Größe = 64kb). Wenn du nun 10 x klickst und der aber nur 1 mal geschickt hat in der Zwischenzeit, so landen alle Daten, die noch geschickt werden müssen, im Puffer (9x).
Überschreibt dies den Puffer, so kommts zu nem Fehler und die Sendefunktion liefert als Result 0 oder einen negativen Wert zurück.
Das kann dann der Fall sein, wenn zB nur 4 weitere Datensätze reinpassen in den Puffer - damit wären wir bei den 5 Befehlen, die auch ankommen - so wie von dir beschrieben.

Lösung des Problemes - reagiere auf den Resultwert von der Sendefunktion.
Lege selbst (am besten einen) Queue Puffer an, dem du Datensätze draufpusht und der seperat abgearbeitet wird - per Sendebefehl wird solange gesendet, bis alle Datenabgerbeitet werden; und der Datenpointer wird natürlich um die Anzahl der Bytes, die geschickt wurden, inkrementiert. Kann mal etwas nicht geschickt werden, sei es nun weil der Puffer zu klein ist (oder sonstwas) so inkrementierst du einfach deinen Datenpointer nicht und beim nächsten Sendeversuch wird nochmal probiert usw. usf

Zu deinem Geschwindigkeitsproblem - ich weiß nicht, wie du das ganze nun wirklich gelöst hast, aber, sofern der Server schnell ist, sollte es da eig. keine Probleme geben. Evt. würde ich mir überlegen, von TCP auf UDP zu wechseln, sofern du das nicht bereits hast!

mjustin 19. Mär 2012 11:35

AW: TSocket - Online Spiel Kommunikation
 
Zitat:

Zitat von mamble (Beitrag 1157280)
Sollte ich was anderes als TSocket verwenden?

Mit Indy (oder Synapse) als TCP/IP Socketbibliothek erreiche ich lokal auf einem alten Notebook zwischen fünf- und zwanzigtausend Nachrichten (pro Sekunde). So schnell kann man nicht tippen :)

An TCP kann es eigentlich nicht liegen, eher ist etwas im Code ineffizient.

mamble 19. Mär 2012 15:08

AW: TSocket - Online Spiel Kommunikation
 
Zitat:

Zitat von Aphton (Beitrag 1157286)

Lösung des Problemes - reagiere auf den Resultwert von der Sendefunktion.
Lege selbst (am besten einen) Queue Puffer an, dem du Datensätze draufpusht und der seperat abgearbeitet wird - per Sendebefehl wird solange gesendet, bis alle Datenabgerbeitet werden; und der Datenpointer wird natürlich um die Anzahl der Bytes, die geschickt wurden, inkrementiert.

Okay, das Problem das du eben beschrieben hast, das hab' ich verstanden, allerdings verstehe ich die Lösung nicht ^^ bzw. wie ich das angehen soll, mit so etwas habe ich mich noch nie befasst.

Zitat:

Zitat von Aphton (Beitrag 1157286)
Zu deinem Geschwindigkeitsproblem - ich weiß nicht, wie du das ganze nun wirklich gelöst hast, aber, sofern der Server schnell ist, sollte es da eig. keine Probleme geben. Evt. würde ich mir überlegen, von TCP auf UDP zu wechseln, sofern du das nicht bereits hast!

Ich habe keinen echten Server, sondern eine Serverapplikation. (und diese führe ich mit dem client lokal aus)
Ja, glaube das ich TCP habe ^^ TSocket ist doch Standardmäßig TCP...oder nicht
Warum sollte ich von TCP auf UDP wechseln? ..und wie?


Zitat:

Zitat von mjustin (Beitrag 1157342)
Mit Indy (oder Synapse) als TCP/IP Socketbibliothek erreiche ich lokal auf einem alten Notebook zwischen fünf- und zwanzigtausend Nachrichten (pro Sekunde). So schnell kann man nicht tippen :)

An TCP kann es eigentlich nicht liegen, eher ist etwas im Code ineffizient.

Leider kann ich nicht gut mit Indy, ich weiß nicht wie ich da das realisieren kann, was ich mit TSocket bereits habe.

Das da etwas am Code ineffizient ist kann gut sein... hab nen sehr chaotischen style..

Hier das wichtigste:

Durch Mausklick aus Komponente sendet CLIENTapp an SERVERapp
Delphi-Quellcode:
ClientSocket1.Socket.SendText(Aktion);
<- Clientapp

Und bei der Serverapp im ClientRead folgendes:

Delphi-Quellcode:
procedure TForm2.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var DieAktion:string;
    i: Integer;
begin
    DieAktion:=Socket.ReceiveText;
    Memo1.Lines.add(DieAktion);
    For I := 0 to ServerSocket1.Socket.ActiveConnections - 1 do
    begin
       with ServerSocket1.Socket.Connections [I] do
       if (Connected) then SendText(Text);
   end;
end;
Was mir persönlich jetzt an der ClientRead Prozedur aufgefallen ist, ist die suboptimale Lösung des Senden an alle aktiven Verbindungen... aber was besseres ist mir nicht eingefallen.


Jede Hilfe ist willkommen :)

shmia 19. Mär 2012 15:40

AW: TSocket - Online Spiel Kommunikation
 
Wenn du bei TCP/IP sehr schnell hintereinander Daten sendest, dann stehen die Chancen gut, dass beim Empfänger alles in einem Datenpaket ankommt.
Wenn der Absender z.B. folgendes schickt:
Delphi-Quellcode:
ClientSocket1.Socket.SendText('HIT 120, 50');
for i := 1 to 100 do ; // ganz kleine Pause dazwischen
ClientSocket1.Socket.SendText('HIT 85, 60');
Dann wird beim Empfänger möglicherweise nur ein String mit dem Inhalt "HIT 120, 50HIT 85, 60" ankommen.
Wenn dein Empfänger nicht in der Lage ist die einzelnen Befehle sauber zu trennen, dann kann die Kommunikation nicht korrekt funktionieren.

Aphton hat ja geraten auf den Resultwert der Sendefunktion zu reagieren.
Das ist aber nicht das Problem.
Das Problem ist, dass TCP/IP ein Streamorientiert ist während deine Anwendung Messageorientiert arbeitet.

Code:
StelldireinfachvoreinTextwürdeohneLeerzeichenun
dSatzzeichenübertragenwerdenEinComputerhättedie
grösstenSchwierigkeitendamitzurechtzukommenWofä
ngteinWortoderBefehlanundwohörteraufGenaudasist
dasProblemwennmankeinrichtigesProtokollhatmitde
mdieeinzelnenBefehlegetrenntwerdenkönnen

Aphton 19. Mär 2012 15:50

AW: TSocket - Online Spiel Kommunikation
 
Das ist nicht das Problem, klar, das ist die Lösung!
Also nun nicht zu DEM Problem...
Das war die Lösung zu dem Problem mit verloren gegangenen Paketen.
Das was du ansprichst ist auch sehr wichtig, was er nicht berücksichtigt!

Aphton 19. Mär 2012 15:55

AW: TSocket - Online Spiel Kommunikation
 
Lösungsvorschlag für das Problem mit Pakettrennung/erkennung:

Ein Paket (Datensatz) besteht aus 2 Komponenten:
<Größenangabe der Daten>
<Daten>

Man pusht nun auf den Queue Pakete in genau diesem Format drauf. Dieser wird abgearbeitet (byte für byte wenns sein muss, spielt auf dieser Ebene noch keine Rolle).
Beim Empfangen wird genau jenes auch getan.

Zwischendrin aber versucht der Empfänger rauszufinden, ob ein ganzes Paket schon angekommen ist, indem er zuerst einmal die ersten paar Bytes (Größenangabe der Daten) aus dem Empfangspuffer ausliest und zweitens sicherstellt, dass die Puffergröße >= Größe von <Größenangabe der Daten> + Größenangabe.
Falls die Bedingung zutrifft, so kann er ausgehen, dass ein Paket angekommen ist und poppt diese dann vom Empfangspuffer!

Edit: @Threadstarter
Ich helfe dir nur theoretisch. Ich werde dir keinen Code schreiben!

mjustin 19. Mär 2012 17:44

AW: TSocket - Online Spiel Kommunikation
 
Zitat:

Zitat von Aphton (Beitrag 1157383)
Falls die Bedingung zutrifft, so kann er ausgehen, dass ein Paket angekommen ist und poppt diese dann vom Empfangspuffer!

Das ist bei Indy einfacher - es gibt vordefinierte Funktionen um z.B. Text bis zu einem bestimmten Trennzeichen (CR/LF) in einen String einzulesen, oder eine bestimmte Anzahl Bytes in ein Bytearray (TBytes oder TIdBytes). Indy übernimmt dann das Pufferlesen und Paketzusammensetzen, bis die gewünschten Daten komplett vorhanden sind, oder (bei Netzwerkproblemen oder wenn der Client abgebrochen wurde) ein Timeout auftritt. Ähnliche Funktionen bietet auch Synapse.

Aphton 19. Mär 2012 17:45

AW: TSocket - Online Spiel Kommunikation
 
Meinte er nicht, er wolle kein Indy benützen?
:gruebel:

mjustin 19. Mär 2012 17:54

AW: TSocket - Online Spiel Kommunikation
 
Zitat:

Zitat von Aphton (Beitrag 1157416)
Meinte er nicht, er wolle kein Indy benützen?

Ja, das schrub er, und ich habe auch Synapse erwähnt. Beide arbeiten im Unterschied zu TSocket mit blockierenden Sockets, was aber nur bedeutet dass man mit Threads arbeitet, wenn gleichzeitig noch andere Operationen oder die VCL mit im Spiel sind. Vorteil bei beiden ist dann aber das leichtere Handling, man muss keine Pakete zusammenbauen und kann sich mehr auf das eigene Protokoll konzentrieren.

mamble 21. Mär 2012 16:23

AW: TSocket - Online Spiel Kommunikation
 
Liste der Anhänge anzeigen (Anzahl: 1)
Richtig vorerst will ich kein Indy benutzen. Wenn ich fertig bin werde ich mir das allerdings mal genauer anschauen und dann ergänzen.

Die langsame Kommunikation zwischen Client und Server (die eigentlich nie so vorhanden war) lag im übrigen nicht an den hier erwähnten Problemen, sondern daran das ich ein Panel zum fang des Klicks benutzt habe :D Das dieses die Klicks langsamer registriert und daher suboptimal für mein Programm ist, ist mir erst später eingefallen.

Mittlerweile habe ich die Panelkomponente durch einen (teilweise) unsichtbaren Speedbutton ersetzt... vorerst genügt das, später werde ich nach einer besseren Lösung suchen.

Das von shmia erwähnte Problem ist in in mehreren Testläufen (mit mehreren tausend Klicks) nur ein einziges Mal vorgekommen (ich protokolliere alle vom Server/Client gesendeten/empfangenen Nachrichten).
Dennoch werde ich mit der zeit auf UDP umstellen, sobald ich weiß wie ;)

Danke an alle.

Eine letzte Frage: Ich benutzte RAD Studio XE2. Wenn ich mir die Infos zu T(Client)Socken angucke, dann wird dort aufgeführt das diese Komponente auch OS X unterstützt. (Siehe Anhang)

http://i.imgur.com/zpat1.png

Wenn ich jedoch eine neue Firemonkey-HD Anwendung erstelle und die Komponente benutzen will wird mir diese nicht angezeigt. Was genau ist da los? ^^

shmia 21. Mär 2012 16:32

AW: TSocket - Online Spiel Kommunikation
 
Zitat:

Zitat von mamble (Beitrag 1157801)
Dennoch werde ich mit der zeit auf UDP umstellen, sobald ich weiß wie ;)

Das würde ich mir aber nochmal genau überlegen.
Bei UDP kann es folgende Effekte geben:
1.) einzelne Pakete kommen sporadisch überhaupt nicht an (ohne dass dir das vom Betriebsystem gesagt wird)
2.) Manchmal kommt das gleiche Paket auch zweimal oder öfters an
3.) UDP Pakete können sich gegenseitig überholen (Sender schickt A,B,C und der Emfpänger bekommt A,C,B)

Alle die beschriebenen Effekte sind zwar selten, aber wenn die Software darauf nicht vorbereitet ist kann es ganz böse Fehler geben. :warn:
Bei TCP können die beschriebenen Effekte nicht auftreten, denn das Betriebssystem sorgt dafür, dass alle Daten ohne Verlust in der richtigen Reihenfolge an dein Programm weitergeleitet werden.

mamble 21. Mär 2012 16:40

AW: TSocket - Online Spiel Kommunikation
 
Hast du mir in Post #5 nicht von TCP abgeraten? ^^
Was soll ich denn jetzt machen.

...wenn ich später auf Indy umprogrammiere, mit tcp, ist es ja laut mjustin einfach das durch vordefinierte Funktionen zu lösen.
Das wäre doch eine Möglichkeit, oder siehst du da auch noch ein Problem shmia?

Und bitte hilf mir mal einer bezüglich des oben erw. TSockets Problem für OS X :)

Aphton 21. Mär 2012 16:49

AW: TSocket - Online Spiel Kommunikation
 
Zitat:

Zitat von mamble (Beitrag 1157801)
Das von shmia erwähnte Problem ist in in mehreren Testläufen (mit mehreren tausend Klicks) nur ein einziges Mal vorgekommen (ich protokolliere alle vom Server/Client gesendeten/empfangenen Nachrichten).
Dennoch werde ich mit der zeit auf UDP umstellen, sobald ich weiß wie ;)

Moment mal, hack das ganze nicht deswegen einfach ab!
Ich schätze mal du hast das NUR lokal getestet, wo du (fast) keine Latenz hast. Dieses Problem tretet aber sehr häufig auf! Es ist also nicht davon auszugehen, dass es schon ok sein wird, nur weil dein "kleiner" Test dich davon überzeugt hat (mich haben meine Tests damals auch überzeugt als ich damit rumspielte.. -.-')

BUG 21. Mär 2012 17:12

AW: TSocket - Online Spiel Kommunikation
 
Wegen Nachrichtenverlust von TCP auf UDP umzustellen ist paradox - TCP garantiert die Reihenfolge und dass alle Daten übertragen werden, UDP nicht.
Weil UDP den Overhead für diese Garantien nicht hat, ist es schneller. Dafür können NATs nicht so gut mit UDP umgehen und du musst selbst überlegen, was du machst, wenn Pakete nicht, in der falschen Reihenfolge oder mehrfach ankommen.

mamble 21. Mär 2012 18:33

AW: TSocket - Online Spiel Kommunikation
 
Hab doch schon oben geschrieben das ich auf Indy mit tcp umsteigen werde.
Bei udp wärs blöd wenn die Pakte in einer anderen Reihenfolge ankommen, das hab ich nämlich noch nicht geregelt.

Hat einer nun Ahnung von der TSocket Komponente im Bezug auf OS X?

@Aphton: Ich werd das Spiel gleich außerhalb der lokalen Umgebung, online probieren. Danach werde ich dich über den Status informieren ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:14 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