Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Gutes TCP Protokoll? (https://www.delphipraxis.net/181419-gutes-tcp-protokoll.html)

milos 13. Aug 2014 01:39


Gutes TCP Protokoll?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
Ich habe ein kleines Spiel das ich nun mit einem MP-Modus ausstatten will und überlege mir gerade ein Protokoll.

Ist es Sinnvoll es einfach so simpel wie möglich zu halten? Also ich denke dabei an befehle wie:
Code:
join lobby main
Code:
set direction 90
Und als antwort vom server einfach ein "ok" bzw. "error eine fehlermeldung".
Also das wären halt ganz simple "konsolenbefehle". Wäre dann halt auch sehr einfach hackbar ohne gewisse gegenmassnahmen aber das lässt sich ja teilweise sichern.

Oder wäre es da schon besser wenn man das ganze komplexer aufbaut und z.b. ganze objekte verschickt?

Ausserdem klappt bei mir die Verbindung nicht wirklich. Ich habe versucht eine einfache Verbindung aufzubauen. Zuerst sende ich einfaches Connect und dann will ich den Namen mit "name blabla" setzen aber die Verbindung wird immer wieder geschlossen und ich weiss einfach nicht wieso. :/

Hier der Code:
Client beim Connecten:
Delphi-Quellcode:
procedure TForm1.Connect;
var
  AMessage : string;
begin
  TCPClient.Disconnect;
  TCPClient.Connect;

  SendMessage('connect');

  if ReceiveMessage = 'welcome' then
  begin
    showmessage('Connected!');
    repeat
      Name := InputBox('CrazyCurve', 'Enter your name:', ''); // Diese box wird noch ausgeführt
      SendMessage('name ' + Name); // Wird laut Log nicht zum server gesendet...
    until (ReceiveMessage = 'ok');
    showmessage('Name ok');
  end;
end;
Server beim Execute:
Delphi-Quellcode:
procedure TForm1.TCPServerExecute(AContext: TIdContext);
var
  AMessage : string;
  Commands : TStringList;
  First : string;
begin
  AMessage := ReceiveMessage(AContext);

  if AMessage = 'connect' then
  begin
    AnswerMessage(AContext, 'welcome');
  end;

  Split(' ', AMessage, Commands);

  if Commands[0] = 'name' then
    AnswerMessage(AContext, 'ok');

end;

Hier noch SendMessage und ReceiveMessage:
Delphi-Quellcode:
function TForm1.ReceiveMessage: string;
begin
  Result := TCPClient.IOHandler.ReadLn();
  ReceivedMessage := Result;
end;

procedure TForm1.SendMessage(AMessage: string);
begin
  TCPClient.IOHandler.WriteLn(AMessage);
end;
Beim Server ist das noch mit AContext von TidContext.

Die 2 Projekte sind noch im Anhang.

Hoffe einer kann mir da weiter helfen, ich weiss wirklich nicht warum das programm da anhalten sollte :/

MfG

Sherlock 13. Aug 2014 07:16

AW: Gutes TCP Protokoll?
 
Ja, die Indys sind meiner Meinung nach nicht wirklich intuitiv, aber dafür sehr mächtig. Ich verwende für das bisschen TCP das ich brauche Francois Piettes Sicht der Dinge.
Du solltest Dich aber in die Indys einlesen, die Doku ist ganz gut, und am Ende hast Du das Wissen für richtig tolle Dinge.

Sherlock

Puke 13. Aug 2014 13:09

AW: Gutes TCP Protokoll?
 
Zitat:

Zitat von milos (Beitrag 1268516)
Delphi-Quellcode:
  SendMessage('connect');

Bist du sicher, dass du hier die Indys benutzt (Ein Tipp: Rechtsklick auf SendMessage/ Deklaration suchen). Meiner Meinung nach sieht das nach Winapi aus.

Kann leider nichts ausprobieren ohne Delphi,
Puke

Sherlock 13. Aug 2014 14:15

AW: Gutes TCP Protokoll?
 
Ich hatte aus einem kurzen Blick in die Quellen angenommen es würden die Indys verwendet, ich habe da da hoffentlich nicht vorschnell geurteilt.

Sherlock

milos 13. Aug 2014 14:36

AW: Gutes TCP Protokoll?
 
Ja ich benutze die Indy Komponente. Jedoch funktioniert die Verbindung nicht ganz :/

Ich habe die Funktion SendMessage von der WinAPI überschrieben mit SendMessage zum schreiben einer Nachricht mit den Indy Komponente.

Steht auch im ersten Beitrag: ^^
Zitat:

Zitat von milos
Hier noch SendMessage und ReceiveMessage:
Delphi-Quellcode:
function TForm1.ReceiveMessage: string;
begin
  Result := TCPClient.IOHandler.ReadLn();
  ReceivedMessage := Result;
end;

procedure TForm1.SendMessage(AMessage: string);
begin
  TCPClient.IOHandler.WriteLn(AMessage);
end;
Beim Server ist das noch mit AContext von TidContext.


Puke 13. Aug 2014 15:28

AW: Gutes TCP Protokoll?
 
Habs mal ausprobiert :roll: Windows hochzufahren ist sehr langweilig

Ich würde bei,
Delphi-Quellcode:
TCPServerExecute
erstmal überprüfen, ob überhaupt eine Message gesendet wurde. Denn wenn du es nicht tust, bleibt er bei
Delphi-Quellcode:
ReadLn
hängen, wenn du
Delphi-Quellcode:
TCPClient.Connect
ausführst. Weiterhin musst du irgendwo dem Client mitteilen wo sich dein Server befindet (Ich nehme mal localhost an)

Wenn also der Connect gutgeht, kannst du dein 'Connect' senden. Dabei wird dir beim debuggen auffallen, dass das 'C' abgeschnitten wird. Du kannst allerdings einen weiteren Buchstaben davorsetzen und fragst dann trotzdem nach 'Connect' (ging soweit bei mir gut).

Mehr Zeit hab ich leider net, also viele Grüße
Puke

sx2008 13. Aug 2014 18:58

AW: Gutes TCP Protokoll?
 
Also der Datenaustausch über TCP hat mindestens 3 Aspekte:
a.) welche Bibliothek (Indy, ICS, Fastnet,...) verwendet man und wie benützt man dessen API?
b.) wie sorgt man dafür dass die einzelnen Messages beim Empfänger korrekt getrennt werden?
Dies wird sehr häufig überhaupt nicht bedacht und daher meistens falsch umgesetzt!
c.) das Protokoll selbst - muss es erweiterbar sein? Soll es einen hierarchischen Datenaufaufbau (z.B. XML, JSON, S-Expressions) haben oder reicht ein einfacheres Protokoll ähnlich wie SMTP?
Wurde ein NOOP-Befehl vorgesehen?
Hat man einen Parser für das Protokoll (sollte man bei hierarchischem Aufbau haben)

Wenn man ein eigenes Protokoll entwickeln möchte braucht man eigentlich kein Indy sondern es reicht auch die Unit Scktcomp mit den Klassen TServerSocket und TClientSocket aus.

mjustin 14. Aug 2014 06:47

AW: Gutes TCP Protokoll?
 
Delphi-Quellcode:
procedure TForm1.TCPServerExecute(AContext: TIdContext);
var
  AMessage : string;
  Commands : TStringList;
  First : string;
begin
  AMessage := ReceiveMessage(AContext);

  if AMessage = 'connect' then
  begin
    AnswerMessage(AContext, 'welcome');
  end;

  Split(' ', AMessage, Commands);

  if Commands[0] = 'name' then
    AnswerMessage(AContext, 'ok');

end;

function TForm1.ReceiveMessage: string;
begin
  Result := TCPClient.IOHandler.ReadLn();
  ReceivedMessage := Result;
end;
Das sieht böse aus :) Der Server ruft in OnExecute ReceiveMessage auf und in ReceiveMessage wird auf den IOHandler des Clients zugegriffen. Der Servercode darf niemals direkt auf den Clientcode zugreifen, sondern muss seinen eigenen IOHandler verwenden:
Delphi-Quellcode:
procedure TForm1.TCPServerExecute(AContext: TIdContext);
var
  AMessage : string;
  Commands : TStringList;
  First : string;
begin
  AMessage := AContext.Connection.IOHandler.ReadLn;

  if AMessage = 'connect' then
  begin
    ...

end;

Puke 14. Aug 2014 10:17

AW: Gutes TCP Protokoll?
 
Zitat:

Zitat von milos (Beitrag 1268516)
Beim Server ist das noch mit AContext von TidContext.

Er hat es schon richtig mjustin.


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