AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Befehle trennen

Ein Thema von ByTheTime · begonnen am 2. Sep 2012 · letzter Beitrag vom 2. Sep 2012
Antwort Antwort
ByTheTime

Registriert seit: 24. Sep 2011
Ort: Frankfurt
297 Beiträge
 
Delphi XE2 Architect
 
#1

Befehle trennen

  Alt 2. Sep 2012, 20:43
Moin,
ich bastel an einem Tool, mitdem 2 PC's über die Sockets kommunizieren (Indy war mir irgendwie komisch mit dem Writln und Readln da ). Einer ist der Server, der andere der Client . Jetzt habe ich ein ListView im Report-Modus, wo ein Paar Infos reinkommen. Name, des Clienten (sendet der Client natürlich), IP, Benutz welcher am Remote-PC sitz, Version des Clienten und Ping. Wenn sich der Client verbindet, soll er mir alles außer seiner IP und dem Ping senden (mache ich am Server mit Socket.RemoteAdress). Dafür habe ich mir folgendes überlegt:

Delphi-Quellcode:
procedure TfrmMain.TCPClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Socket.SendText('remoteinfo§' + Name + '#' + ComUser + '#' + APP_VERSION);
end;
'remoteinfo' ist der Befehl, dass das nachfolgende alles die Infos des Remotecomputers sind. '§' ist das Ende des Befehls und '#' grenzen die einzelnen Infos voneinander ab.

Name = Name des Clienten
ComUser = Name des Benutzers, der am PC angemeldet ist
APP_VERSION = Eine konstante mit der Versiond es Clienten

Aber ich weiß nicht wie ich alles voneinander trennen soll. Ich habe zwar das hier, aber ich kriege es nicht zusammen Dazu kommt dann noch wie das mit der Abfrage am Server ist.

Delphi-Quellcode:
procedure TfrmMain.TCPServerClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  case Socket.ReceiveText of
    'Befehl': {das mit dem trennen ist aber jetzt komisch, denn der ReceiveText ist ja nicht nur der Befehl, sonder auch die Info :/ Also muss ich erst Befehl und Info trennen... Irgendwie davor...};
  end;
end;
Hoffe ihr könnt mir auf die Sprünge helfen ...

[EDIT]: Zumindestens weiß ich, wie ich mit Pos mein Befehlszeichen ausmachen kann... Immerhin etwas
Lukas

Geändert von ByTheTime ( 2. Sep 2012 um 20:59 Uhr)
  Mit Zitat antworten Zitat
dominikkv

Registriert seit: 30. Sep 2006
Ort: Gundelfingen
1.109 Beiträge
 
Delphi 2007 Professional
 
#2

AW: Befehle trennen

  Alt 2. Sep 2012, 21:34
Beim Empfangen musst du vorsichtig sein: Das Ereignis wird aufgerufen, sobald Text empfangen wird. Du weißt nicht, ob die komplette Nachricht schon übertragen wurde oder aber ob vielleicht zwei Nachrichten im Buffer stecken.

Das heißt
- das Event kann für eine Nachricht zwei mal aufgerufen werden
- das Event kann kann zwei Nachrichten enthalten

Darum musst du dir einen eigenen Buffer bauen, in den der empfangene Text landet, und wenn du darin eine komplette Nachricht entdeckst kannst du die da rausholen.

Hier ein Beispiel, wie ich das damals gemacht habe:
Delphi-Quellcode:
const
  MessageDelimitter = '%%';

procedure TMyServer.OnServerClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  msg : string;
  Client: TSClient;
begin
  msg := Socket.ReceiveText;

  if Assigned(fOnRead) then
    fOnRead(self, msg, Socket.RemoteAddress, Socket.RemotePort);

  Client := GetClientByID(GetID(Socket.RemoteAddress, Socket.RemotePort));

  if Assigned(Client) then
    begin
      Client.ReadBuffer := Client.ReadBuffer + msg;

      while Pos(MessageDelimitter, Client.ReadBuffer) > 0 do
        begin
          msg := copy(Client.ReadBuffer, 1, Pos(MessageDelimitter, Client.ReadBuffer) - 1);
          ServerExecute(Client, msg);
          Delete(Client.ReadBuffer, 1, Pos(MessageDelimitter, Client.ReadBuffer) + Length(MessageDelimitter) - 1);
        end;
    end;
end;
Das bedeutet aber, dass du am Ende jeder Nachricht auch ein Zeichen mitsenden musst, dass die Nachricht zu Ende ist. Dann musst du natürlich auch dafür sorgen, dass dieses Zeichen in der eigentlichen Nachricht nicht vorkommt.

Zu deinem Trenner-Problem: Du kannst mit einer TStringList den Text zerlegen.
Delphi-Quellcode:
var
  List: TStringList;
begin
  List := TStringList.Create;
  List.StrictDelimitter := True;
  List.Delimitter := '#';
  List.DelimittedText := 'Wert 1#Wert 2#Banane';

  showmessage(List.Text);
  List.Free;
end;
Ich würde dir aber empfehlen, das ganze zB mit JSON zu verpacken. Dann würde das ganze so aussehen:
Code:
{command:'remoteinfo', body:[name:'Hans', ComUser:'Hans_Workstation', APP_VERSION:123]}
Dann kannst du daraus leicht Objekte machen, zB mit SuperObject. Um mir aus einem Objekt den entsprechenden String zu holen habe ich folgendes benutzt:
Delphi-Quellcode:
function TConverter.GetStr: string;
var
  Context: TSuperRttiContext;
begin
  Context := TSuperRttiContext.Create;

  result := IntToStr(Integer(fType)) + Context.AsJson<TSession>(fObject).AsJSon + MessageDelimitter;

  Context.Free;
end;
Und zurück ging das ganze dann so:

Delphi-Quellcode:
procedure TConverter.SetStr(const Value: string);
var
  Context : TSuperRttiContext;
  Obj : TSession;
  Identifier: TObjIdentifier;
  StrType : string;
  StrObj : string;
begin
  Context := TSuperRttiContext.Create;

  StrType := copy(Value, 1, Pos('{', Value) - 1);
  StrObj := copy(Value, Pos('{', Value), MaxInt);

  Identifier := TObjIdentifier(StrToInt(StrType));

  case Identifier of
    otNone : Obj := NIL;
    otSession : Obj := Context.AsType<TSession>(SO(StrObj));
    otNickChange : Obj := Context.AsType<TNickChange>(SO(StrObj));
    otNachricht : Obj := Context.AsType<TNachricht>(SO(StrObj));
    otKickNachricht: Obj := Context.AsType<TKickNachricht>(SO(StrObj));
    otUserList : Obj := Context.AsType<TUserList>(SO(StrObj));
    otWelcome : Obj := Context.AsType<TWelcome>(SO(StrObj));
  end;

  SetObject(Obj);
  Context.Free;
end;
TNickChange etc sind Klassen von von TSession abgeleitet, damit kannst du dann zB dein Kommando steuern.

Vielleicht hilfts dir
Dominik
Wer anderen eine Grube gräbt, hat ein Gruben-Grab-Gerät!
  Mit Zitat antworten Zitat
ByTheTime

Registriert seit: 24. Sep 2011
Ort: Frankfurt
297 Beiträge
 
Delphi XE2 Architect
 
#3

AW: Befehle trennen

  Alt 2. Sep 2012, 22:17
Ich habe es jetzt doch so gemacht, wie ich es erst nicht machen wollte... Mit dem hier Mit den Kommandos, etc. Muss nun noch schauen wie ich das alles hinbekomme, aber das wird schon klappen Aber JSON muss ich mir unbedingt mal anschauen, habe neulich mit einem bekannten geredet, der hat nur von JSON erzählt "JSON anstatt INI, JSON hier, JSON da..." Ich muss mir das unbedingt mal anschauen, scheint sich zu lohnen. Danke nochmal für deien Mühe
Lukas
  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 21:52 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