![]() |
Indy TCP Client/Server
Hallo,
ich schicke innerhalb einer Sekunde mehrere Datenpakete an einen TCP-Server. Mein Problem: Nach kurzer Zeit kommen auf dem Server keine Daten mehr an. Gleiches Problem wie hier beschrieben: ![]() Hat vielleicht jemand ein paar Ideen/Anregungen? Danke. |
AW: Indy TCP Client/Server
Zitat:
|
AW: Indy TCP Client/Server
Liste der Anhänge anzeigen (Anzahl: 1)
Hier ein kleines Demo-Projekt, um das Ganze zu demonstrieren.
Versand:
Delphi-Quellcode:
Empfang:var I : Integer; Data : TBytes; begin Send.Enabled := False; Application.ProcessMessages; for I := 1 to 10000 do begin SetLength(Data, SizeOf(Integer)); Move(PByte(I), Data[0], SizeOf(Integer)); FClient.IOHandler.Write(LongInt(Length(Data))); FClient.IOHandler.Write(Data); end; end;
Delphi-Quellcode:
var
DataSize : LongInt; Data : TBytes; Value : Integer; begin if AContext.Connection.IOHandler.Readable then begin DataSize := AContext.Connection.IOHandler.ReadLongInt; AContext.Connection.IOHandler.ReadBytes(Data, DataSize); Value := 0; Move(Data[0], PByte(Value), SizeOf(Integer)); TThread.Queue ( TThread.CurrentThread, procedure begin UI.Caption := IntToStr(Value); end ); end; end; |
AW: Indy TCP Client/Server
Zitat:
|
AW: Indy TCP Client/Server
Dein Sender schickt immer 4 Byte Länge + Nutzdatenblock.
Der Empfänger muss folgende Strategie anwenden. 1.) empfangener Datenblock an den Empfangpuffer anfügen (anhängen) Jede TCP/IP-Verbindung benötigt ihren eigenen Empfangspuffer 2.) Falls Länge Empfangspuffer < 4 nichts tun (Exit; ) 3.) die ersten 4 Bytes aus Empfangspuffer als Längenfeld auslesen 4.) falls Länge Empfangspuffer < Längenfeld + 4 dann nichts tun (Exit; ) 5.) Aus dem Empfangspuffer werden die 4 Bytes + der Nutzdatenblock ausgeschnitten Der Nutzdatenblock wird über ein Event der weiteren Verarbeitung zugeführt 6.) Gehe zu 2.) Nur so gelingt eine saubere Kommunikation! |
AW: Indy TCP Client/Server
Zitat:
|
AW: Indy TCP Client/Server
Zitat:
Ich kann die Befehle + Daten in eine threadsichere Queue packen und dann versenden. Ändert das überhaupt was?
Delphi-Quellcode:
Im Thread, der für das Versenden zuständig ist:
procedure Invoke(const ACommandID: Integer; const AData: TBytes);
begin Queue.Push(TCommand.Create(ACommandID, AData); EventSend.SetEvent; end;
Delphi-Quellcode:
procedure TSendThread.Execute;
var Command : TCommand; begin WaitForSingleObject(EventSendHandle, INFINITE); Command := Queue.Pop; // Daten versenden end; |
AW: Indy TCP Client/Server
So funktioniert es:
Delphi-Quellcode:
var
DataSize : LongInt; Data : TBytes; Value : Integer; begin AContext.Connection.IOHandler.CheckForDataOnSource(10); if not AContext.Connection.IOHandler.InputBufferIsEmpty then begin DataSize := AContext.Connection.IOHandler.ReadLongInt; AContext.Connection.IOHandler.ReadBytes(Data, DataSize); Value := 0; Move(Data[0], PByte(Value), SizeOf(Integer)); TThread.Queue ( TThread.CurrentThread, procedure begin UI.Caption := IntToStr(Value); end ); end; end; Zitat:
|
AW: Indy TCP Client/Server
Zitat:
Angenommen es treffen 1500 frische Bytes beim Empfänger ein. Dann wird folgender Code ausgeführt
Delphi-Quellcode:
Was aber wenn Datasize=2000 aber es sind nur 1496 Bytes im Puffer?
if not AContext.Connection.IOHandler.InputBufferIsEmpty then
begin // 4 Bytes auslesen DataSize := AContext.Connection.IOHandler.ReadLongInt; // Nutzdaten lesen AContext.Connection.IOHandler.ReadBytes(Data, DataSize); Dann werden bei ReadBytes auch nur 1496 Bytes gelesen. (Sollte man nicht den Rückgabewert von ReadBytes() auswerten?) Alle folgende Datenpakete werden dann falsch interpretiert!! Denn sobald die restlichen Daten eintreffen "denkt" der Empfänger er würde wieder eine Längenangabe bekommen, in Wirklichkeit sind es aber 4 Byte aus der Mitte eines Nutzdatenblocks. |
AW: Indy TCP Client/Server
Zitat:
Delphi-Quellcode:
ist eine Prozedur, daher ist der Rückgabewert unproblematisch.
procedure ReadBytes(var VBuffer: TIdBytes; AByteCount: Integer; AAppend: Boolean = True); virtual;
Aber der dritte Parameter ist verdächtig: wenn VBuffer bereits Daten enthält, werden neue Daten angehängt. Nach ReadBytes sollten die Daten doch bereits in Data stehen, was macht dann diese Zeile?
Delphi-Quellcode:
Move(Data[0], PByte(Value), SizeOf(Integer));
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz