Entwickler-Ecke

Internet / Netzwerk - Daten werden "verschluckt"


glotzer - Fr 07.01.11 03:20
Titel: Daten werden "verschluckt"
hallo zu doch sehr später stunde:

senden:

Delphi-Quelltext
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:
[...]

const
  P_DebugMsg      = 0;
  P_Quit          = 1;
  P_RequireLogin  = 10;
  P_SendLogin     = 11;

[...]

constructor TClient.Create(AContext: TIdContext);
begin
  inherited Create;
  Thread := AContext;
  ClientList.Add(self);
  Begining(AContext);
end;

procedure TClient.Send (msg: String);
begin
  Thread.Connection.Socket.WriteLn(msg);
end;

procedure TClient.Begining (AContext: TIdContext);
begin
  //Require loging in
  RandomValue := 5;//Random(2147483647);
  Send(MakeProtokollLine(P_RequireLogin,inttostr(RandomValue)));
  LoggedIn := false;
end;

[...]

function MakeProtokollLine (Tooken: Integer; line: String):String;
var
  PartLow,PartHighe:Integer;
begin
  if Tooken > P_Max then
  begin
    MakeProtokollLine(P_DebugMsg,'Tried to call "MakeProtokollLine('+inttostr(tooken)+','+line+')"');
  end else
  begin
    if not CheckForBlockedTooken(Tooken) then
    begin
      PartHighe := Tooken div 127;
      PartLow   := Tooken-(Tooken div 127)*127;
      result    := Char(PartHighe)+Char(PartLow)+line;
    end;
  end;
end;

[...]


Empfangen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TClientMainForm.ReadConnection;
var
  Tooken: Integer;
  line: String;
begin
  Buffer := TidTCPClient.Socket.ReadLn;
  ExtractProtokollLine(Buffer,Tooken,line);
  InterpreteLine(Tooken,line);
end;

procedure TClientMainForm.InterpreteLine(Tooken: Integer; line: String);
begin
  debugmsg('('+inttostr(Tooken)+')'+line);
end;

procedure ExtractProtokollLine (input:Stringout Tooken: Integer; out line: String);
begin
  Tooken := Integer(input[1])*127+Integer(input[2]);
  line := RightStr(input,length(input)-2);
end;


mein problem: Das tooken geht teilweise verloren, das heißt es kommt komischerweise manchmal an, manchmal auch nicht.
wenn ich

Delphi-Quelltext
1:
MakeProtokollLine(P_DebugMsg,'')                    

abschicke kommt alles an wie es soll.
aber bei

Delphi-Quelltext
1:
Send(MakeProtokollLine(P_RequireLogin,inttostr(5)));                    

kommt eben nur 5 an.
ich bin am verzweifeln un dhab einfach keine idee mehr wie das kommt.

verwendet wird:
Delphi XE
IndyTCPClient/Server

danke im vorraus :D


Klabautermann - Fr 07.01.11 13:34

Hallo,

ich rate jetzt ein wenig ins Blaue, aber vielleicht lande ich ja einen Treffer :roll:.
Ich vermute, dass die 0 (null) (oder andere böse Steuerzeichen schuld) ist.

Dein gesendeter Beispielstring müsste ja so aussehen: #0#11'5'. Meine Mutmaßung ist nun, das irgend etwas auf dem Weg schon anfängt dies zu interpretieren und eventuell zu beschneiden. #0 ist schon mal verdächtig, da es in der C-Welt das String-Ende-Zeichen ist. Verwenden die Indys eine in C-Implementierte DLL welche diesen String übergeben bekommen? #11 wäre ein Vertikales Tab, ich wüsste nicht, wer das interpretieren sollte aber ausschließen kann ich es auch nicht.

Generell würde ich empfehlen das Datenvolumen ein wenig zu erhöhen und dafür die Token dann auch als String zu senden. Der Einfachheit halber vielleicht mit je drei Stellen fester Länge, so das da '0000115' bei heraus käme. Das schließt Fehlerquellen wie die von mir unterstellten aus. Aber natürlich kann ich auch völlig daneben liegen.

Gruß
Klabautermann

PS: Du gehst der Brechung nach davon aus, das Token immer Positiv und höchstens 16 Bit breit ist, eventuell wäre es dann klüger den Datentyp Word anstelle von Integer zu wählen.


jaenicke - Fr 07.01.11 14:15

Vor allem benutzt du Delphi XE. Das heißt in dem String stehen immer zwei Zeichen pro Buchstabe. Hier wäre wohl AnsiString geeigneter. (Auch wenn ich jetzt nicht genauer geschaut habe was du da genau machst.)


glotzer - Fr 07.01.11 17:00


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function MakeProtokollLine (Tooken: Integer; line: String):String;
begin
  if Tooken > P_Max then
  begin
    MakeProtokollLine(P_DebugMsg,'Tried to call "MakeProtokollLine('+inttostr(tooken)+','+line+')"');
  end else
  begin
    if not CheckForBlockedTooken(Tooken) then
    begin
      result    := Format('%'+inttostr(P_TookenLength)+'d',[Tooken])+line;
    end;
  end;
end;

procedure ExtractProtokollLine (input:Stringout Tooken: Integer; out line: String);
begin
  Tooken := StrToInt(LeftStr(input,P_TookenLength));
  line := RightStr(input,length(input)-P_TookenLength);
end;


so funktionierts :D danke euch beiden


Klabautermann - Mo 10.01.11 23:08

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Vor allem benutzt du Delphi XE. Das heißt in dem String stehen immer zwei Zeichen pro Buchstabe. Hier wäre wohl AnsiString geeigneter. (Auch wenn ich jetzt nicht genauer geschaut habe was du da genau machst.)

Stimmt, da war ja noch was :)