|
Registriert seit: 3. Sep 2004 4.629 Beiträge Delphi 10.2 Tokyo Starter |
#1
Hi,
ihr kennt sicher das Problem, wenn man mit den Sockets arbeitet, dass folgender Aufruf:
Delphi-Quellcode:
Oftmals auch dazu führen kann, dass beim Empfänger "HalloBye" als Text ankommt. Wenn man nun noch mit Befehlen und Parameterstrukturen arbeitet, wird die ganze Sache schon etwas komplizierter ...
Socket.SendText('Hallo');
Socket.SendText('Bye'); Die Befehlsreferenz: SetParams Wird eigentlich nicht benötigt, es sei denn, man will die Trenn- und Befehlszeichen ändern. GetCMDString Generiert einen Commando String aus einem Befehlswert und Parametern GetPartitialCMDString Generiert einen Commando Teilstring aus den Parts GetLimitedCMDString Generiert Befehlsblöcke mit einem einstellbaren Zeichenlimit ParseCommands Parst einen Commando String und gibt die einzelnen Befehle zurück ParseParameter Gibt die einzelnen Parameter + Command eines Befehls zurück Die Unit:
Delphi-Quellcode:
Allerdings könnte es Probleme geben, wenn ein RETSIGN im Befehl vorkommt und das RETSIGN zufällig das letzte gesendete Zeichen von einem Block ist. Leider habe ich noch keinen Ansatz gefunden, wie ich dieses Problem vermeiden kann.
////////////////////////////////////////////////////////////////////////////////
/// UNIT ProtocolUtils ///////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// /// /// Copyright © 2006 by Florian Bernd /// /// [url]www.bernd-boppard.de[/url] /// /// /// /// Dieses Copyright darf nicht entfernt oder geändert werden! /// /// Über eine Benennung in den Credits würde ich micht freuen, jedoch ist /// /// dies nicht zwingend erforderlich. /// /// /// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// unit ProtocolUtils; interface uses Classes, Windows, SysUtils; //Paramter setzen procedure SetParams(fDELIMITER, fCMDSIGN, fRETSIGN, fQUOTE, fPQUOTE: Char); //Commando String erstellen function GetCMDString(Command: string; Params: array of string): string; //Teilweisen Commando String erstellen function GetPartitialCMDString(Parts: array of string; CommandBegin, EndOfData: boolean): string; //Commandos parsen function ParseCommands(CmdLine, Buffer: string; Commands: TStringList): string; //Commandostring erstellen und nach Zeichen begrenzt ausgeben procedure GetLimitedCMDString(Command: string; Params: array of string; Limit: integer; Parts: TStringList); //Die Parameter eines Befehls bekommen procedure ParseParameter(Command: string; Params: TStringList); var DELIMITER: Char = '|'; //Trennzeichen für Parameter CMDSIGN : Char = '*'; //Trennzeichen für die Befehle RETSIGN : Char = '#'; //Endzeichen für einen Befehl QUOTE : Char = '"'; //Quote Zeichen für die Befehle PQUOTE : Char = '~'; //Quote Zeichen für die Parameter implementation //Splittet einen Text anhand eines Delimiters in seine Einzelteile auf function Split(const fText: String; const fSep: Char; fTrim: Boolean = false; fQuotes: Boolean = false; QuoteChar: Char = '"'): TStringList; var vI, vOffset: Integer; vBuffer: String; vOn: Boolean; begin Result := TStringList.Create; vBuffer := ''; vOffset := 0; vOn := true; for vI := 1 to length(fText) do begin if (fQuotes and (fText[vI] = fSep ) and vOn) or (not (fQuotes) and (fText[vI] = fSep)) then begin if fTrim then vBuffer := Trim(vBuffer); if vBuffer = '' then vBuffer := fSep; // !!! sonst läuft z.B. split(',**',',') auf einen Hammer... if vBuffer[1] = fSep then vBuffer := Copy(vBuffer, 2, Length(vBuffer)); Result.Add(vBuffer); vBuffer := ''; end; if fQuotes then begin if fText[vI] = QuoteChar then begin vOn := Not(vOn); if Copy(fText, vI + vOffset, 2) = QuoteChar + QuoteChar then begin vBuffer := vBuffer + QuoteChar; vOffset := vOffset + 1; end else begin vOffset := 0; end; Continue; end; if (fText[vI] <> fSep) or ((fText[vI] = fSep) and (vOn = false)) then vBuffer := vBuffer + fText[vI]; end else if fText[vI] <> fSep then vBuffer := vBuffer + fText[vI]; end; if vBuffer <> '' then begin if fTrim then vBuffer := Trim(vBuffer); Result.Add(vBuffer); end; end; //Ersetzt einfache Quotes in durch Zweifache function Prepare(Text: string): string; begin Result := StringReplace(Text, QUOTE, QUOTE + QUOTE, [rfReplaceAll]); Result := StringReplace(Result, PQUOTE, PQUOTE + PQUOTE, [rfReplaceAll]); end; procedure SetParams(fDELIMITER, fCMDSIGN, fRETSIGN, fQUOTE, fPQUOTE: Char); begin DELIMITER := fDELIMITER; CMDSIGN := fCMDSIGN; RETSIGN := fRETSIGN; QUOTE := fQUOTE; PQUOTE := fPQUOTE; end; function GetCMDString(Command: string; Params: array of string): string; var i: integer; begin //Befehl hinzufügen Result := QUOTE + CMDSIGN + PQUOTE + Prepare(Command) + PQUOTE + DELIMITER; //Alle Parameter hinzufügen for i := 0 to length(Params) -1 do begin Result := Result + PQUOTE + Prepare(Params[i]) + PQUOTE + DELIMITER; end; //Abschließende Befehlszeichen hinzufügen Result := Result + QUOTE + RETSIGN + CMDSIGN; end; function GetPartitialCMDString(Parts: array of string; CommandBegin, EndOfData: boolean): string; var i: integer; begin //Wenn CommandBegin, dann wird der erste Teil als Command verwendet if CommandBegin then Result := QUOTE + CMDSIGN + PQUOTE; //Alle Teile hinzufügen for i := 0 to length(Parts) -1 do begin if CommandBegin then Result := Result + PQUOTE + DELIMITER + PQUOTE + Prepare(Parts[i]) + PQUOTE else Result := Result + DELIMITER + PQUOTE + Prepare(Parts[i]) + PQUOTE end; //Wenn EndOfData, dann werden die abschließenden Befehlszeichen angehängt if EndOfData then Result := Result + DELIMITER + QUOTE + RETSIGN + CMDSIGN; end; function ParseCommands(CmdLine, Buffer: string; Commands: TStringList): string; var i: integer; CMDList: TStringList; begin //Comammands leeren Commands.Clear; try CMDList := Split(Buffer + CmdLine, CMDSIGN, false, true, QUOTE); //Wenn kein vollständiger Befehl vorhanden ist ... if CMDList.Count < 1 then begin //... und der Buffer nicht leer ist ... (Der Befehl kann nie vollständig //werden, wenn nicht mindestens das Befehlszeichen im Buffer ist) if Buffer <> '' then begin //... den neuen Buffer zurückgeben und die Stringliste leeren Result := Buffer + CmdLine; CMDList.Clear; end; end else begin //Wenn mindestens ein vollständiger Befehl vorhanden ist die Befehlsliste //in einer Schleife durchgehen und ... for i := 0 to CMDList.Count -1 do begin //... fals das letzte Zeichen nicht das abschließende Befehlszeichen ist //... if Copy(CmdList[i], length(CmdList[i]), 1) <> RETSIGN then begin //... muss dies die letzte Zeile der Stringliste sein und somit ist //auch klar, dass der letzte Befehl nicht vollständig ist. Daher wird //die komplette letzte unvollständige Befehlszeile als neuer Buffer //zurückgegeben Result := QUOTE + CmdList[i]; end else begin //... fals doch, dann enthält die aktuelle Zeile einen vollständigen //Befehl und kann in der Commando Stringliste eingetragen werden Commands.Add(Copy(CMDList[i], 1, length(CmdList[i]) -1)); end; end; end; finally CMDList.Free; end; end; procedure GetLimitedCMDString(Command: string; Params: array of string; Limit: integer; Parts: TStringList); var i: integer; TmpCmd, TmpPart: string; begin //Die Ergebnissliste leeren Parts.Clear; //Einen CMDString mit dem vorgegebenen Parametern generieren TmpCmd := GetCMDString(Command, Params); //Das Ergebniss in einer Schleife durchgehen und immer Limit Zeichen in die //Ergebnissliste kopieren for i := 0 to (length(TmpCmd) div Limit) do begin TmpPart := Copy(TmpCmd, (i * Limit) +1, Limit); if TmpPart <> '' then Parts.Add(TmpPart); end; end; procedure ParseParameter(Command: string; Params: TStringList); var ParamList: TStringList; begin ParamList := TStringList.Create; try //Die Parameter eines Befehls zurückgeben ParamList := Split(Command, DELIMITER, false, true, PQUOTE); Params.Text := ParamList.Text; finally ParamList.Free; end; end; end. |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |