Autor Beitrag
Tobi482
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 135



BeitragVerfasst: So 24.07.11 09:47 
Hallo Leute,

ich habe ein Problem mit den Indy 10 TCP Komponenten. Ich musste vor ein paar Tagen meinen PC formatieren und neumachen und seitdem funktionieren einige meiner Programme nicht mehr. Die alten Binaries funktionieren (compiliert vor der Formatierung); Neue Compilate jedoch nicht. Der Quellcode wurde nicht geändert.

Bei dem Tool handelt es sich um einen TCP-Redirector. Ein Netzwerk-Debug-Tool das einen Socket öffnet, an dem sich dann ein Client anmeldet und die Daten an eine andere IP weiterleitet. Die einzelnen Datenpakete haben jeweils die richtige Größe, jedoch sind die Daten aber dem 5 oder 6 Byte falsch. Ich habe zur Kontrolle einen TCP/IP Sniffer mitlaufen lassen. Dieser empfängt die korrekten Daten (strange?).

Die Idee stammt dabei aus diesem Tutorial.
How to write a TCP Redirector using Indy

ToClient = Socket der mit dem Clienten verbunden ist
ToServer = Socket der mit dem Server verbunden ist

ausblenden volle Höhe 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:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
procedure Tmain.ToClientExecute(AContext: TIdContext);
Var
     Data      : String;
begin
     Try
          Try
               //Connect to Server
               ToServer.Host := 'xxx.xxx.xxx.xxx';
               ToServer.Port := xxxxx;
               ToServer.Connect;

               AContext.Connection.Socket.ReadTimeout := 1000;

               //rename Socket
               ToClientt := AContext;

               //Read/Write loop
               repeat
                    //if there is any data from client
                    if not AContext.Connection.Socket.InputBufferIsEmpty then
                    begin
                         data := AContext.Connection.Socket.InputBufferAsString;;
                         OnSend(ToServer, Data);
                    End;

                    //if there is any data from server
                    if not ToServer.Socket.InputBufferIsEmpty then
                    begin
                         Data := ToServer.Socket.InputBufferAsString;
                         OnRecv(AContext, Data);
                    end;

                    //Check for Disconnects
                    //ToServer.Socket.CheckForDisconnect(False);
                    //ToServer.CheckForGracefulDisconnect(False);
                    //AContext.Connection.Socket.CheckForDisconnect(False);
                    //AContext.Connection.CheckForGracefulDisconnect(False);

                    //Release system slizes
                    SleepEx(1, True);
               until (not AContext.Connection.Connected) or (not ToServer.Connected);
          Finally

               if not AContext.Connection.Connected then
               begin
                    Addlog('ToClient Disconnected');
               end;

               if not ToServer.Connected then
               begin
                    Addlog('ToServer Disconnected');
               end;

               if Assigned(ToServer) then
               Begin
                    ToServer.Disconnect;
                    ToServer.Free;
               End;

               //disconnect from client
               AContext.Connection.Disconnect;
          end;
     Except

     End;
end;


Das Problem konnte zeilweise (1,2 Pakete) mit dem zusätzlichen Clear des Buffers behoben werden. Ich vermute es kann vielleicht mit dem Threading und der Synchonisation zusammen hängen.

Ich bin für jede Hilfe dankbar, meist sieht man den Wald vor lauter Bäumen nicht.

Mit freundlichen Grüßen
Tobi
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19338
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 24.07.11 12:34 
Du solltest besser FreeAndNil(ToServer) statt ToServer.Free benutzen, damit es nach der Freigabe auch nil ist.

Wo synchronisierst du denn? In OnSend usw.?

Und benutzt du vielleicht eine andere Indyversion? Es gibt diverse Unterversionen in Version 10...
Vielleicht hattest du vorher die aktuelle nachinstalliert und nutzt jetzt eine ältere integrierte Version oder so?
Tobi482 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 135



BeitragVerfasst: So 24.07.11 13:13 
versuche schon seit einigen stunden mit unearasern rasu zubekommen welche version ich hatte. kriege ich aus den alten binaries vllt raus welche version verwendet wurde? finde im assemlber wenig infos zu den indy sachen, kaum strings und die analyse des codes wäre ein erheblicher mehraufwand. glaubst du das ein delphi decompiler helfen könnte?

Gruß Tobi
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 25.07.11 06:42 
Zuerst würde ich einmal den Code etwas reinigen ...

ausblenden volle Höhe 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:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
procedure Tmain.ToClientExecute(AContext: TIdContext);
Var
    Data : String;
begin
    If not Assigned(ToServer) Then
    Begin
        Exit;
    end;

    Try
        //Connect to Server
        ToServer.Host := 'xxx.xxx.xxx.xxx';
        ToServer.Port := xxxxx;
        ToServer.Connect;

        AContext.Connection.Socket.ReadTimeout := 1000;

        //rename Socket
        ToClientt := AContext;

        //Read/Write loop
        while AContext.Connection.Connected and ToServer.Connected do
        begin
            try
                //if there is any data from client
                if not AContext.Connection.Socket.InputBufferIsEmpty then
                begin
                    Data := AContext.Connection.Socket.InputBufferAsString;
                    OnSend(ToServer, Data);
                end;
            except
                on E: Exception do
                    ;
            end;

            try
                //if there is any data from server
                if not ToServer.Socket.InputBufferIsEmpty then
                begin
                    Data := ToServer.Socket.InputBufferAsString;
                    OnRecv(AContext, Data);
                end;
            except
                on E: Exception do
                    ;
            end;

            Try
                //Check for Disconnects
                //ToServer.Socket.CheckForDisconnect(False);
                //ToServer.CheckForGracefulDisconnect(False);
                //AContext.Connection.Socket.CheckForDisconnect(False);
                //AContext.Connection.CheckForGracefulDisconnect(False);
            except
                on E: Exception do
                    ;
            end;

            //Release system slizes
            SleepEx(1, True);
        end;
    Finally
        if Assigned(ToServer) then
        Begin
            ToServer.Disconnect;
            FreeAndNil(ToServer);
        end
        else if not ToServer.Connected then
        Begin
            Addlog('ToServer Disconnected');
        end;

        if not AContext.Connection.Connected then
        begin
            Addlog('ToClient Disconnected');
        end;

        //disconnect from client
        AContext.Connection.Disconnect;
    end;
end;


Bzgl. der Exceptions in der On-Angabe schauen, was von den Indy's geworfen werden kann als IO-Exceptions und nur diese fangen.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Tobi482 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 135



BeitragVerfasst: Mo 25.07.11 12:19 
ich bin etwas weiter gekommen, ersteinmal danke schön für eure antworten. da die daten nur teilweise falsch ankommen, habe ich versucht ein muster zu finden

RR = richtiger Hexcode
FF = falscher Hexcode

RR RR RR RR RR FF FF FF RR RR RR RR RR FF RR RR FF FF FF FF RR RR RR

die nachricht sieht richtig aus (Länge, Anfang, Ende) nur in der Mitte geht es teilweise
drunter und drüber.

ich habe raus bekommen, dass sehr viele falsche zeichen mit dem code 0x3F = '?' ersetzt werden. ist das zufall? warum sollte die indy komponente einige bytes mit fragezeichen ersetzen?

hat jemand so etwas schon mal beobachtet?

Mit freundlichen Grüßen
Tobi
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 25.07.11 12:21 
Moin!

user profile iconTobi482 hat folgendes geschrieben Zum zitierten Posting springen:
ich habe raus bekommen, dass sehr viele falsche zeichen mit dem code 0x3F = '?' ersetzt werden. ist das zufall? warum sollte die indy komponente einige bytes mit fragezeichen ersetzen?

hat jemand so etwas schon mal beobachtet?
Sowas habe ich schonmal beobachtet, und zwar beim Konvertieren eines Unicode-Strings in einen Ansi-String: dabei werden nicht-konvertierbare Zeichen durch ein "?" ersetzt. :idea: ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19338
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 25.07.11 12:39 
Außerdem werden einige Bytes durch das Encoding ersetzt, auch wenn dieses an beiden Enden gleich ist. Da habe ich manuell eingegriffen um das zu verhindern...
Tobi482 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 135



BeitragVerfasst: Mo 25.07.11 13:52 
das mit der unicode codierung/convertiereung war der richtige riecher !!!

nun klappt alles wieder

hier die änderungen

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
     //send paket to server
     ToServer.Socket.Write(Paket, TIdTextEncoding.ASCII, TIdTextEncoding.ASCII);

     ...

     Data := ToServer.Socket.InputBufferAsString(TIdTextEncoding.ASCII, TIdTextEncoding.ASCII);
     ...

     Data := AContext.Connection.Socket.InputBufferAsString(TIdTextEncoding.ASCII, TIdTextEncoding.ASCII);


Vielen Dank für eure Hilfe

Tobi