When using a TCP stream there was an option, in the end I went with an original solution for writing a custom TIdIOHandlerStack descendant.
The motivation was that with TIdHTTP I know that it does not work, and I just need to fix it, but when switching to a lower TCP level, new problems arise.
Here's the code I'm using , and I'm going to discuss key points here.
The new TIdStreamIoHandler should inherit from TIdIOHandlerStack .
Two functions need to be rewritten: ReadBytes and ReadStream :
function TryReadBytes(var VBuffer: TIdBytes; AByteCount: Integer; AAppend: Boolean = True): integer; virtual; procedure ReadStream(AStream: TStream; AByteCount: TIdStreamSize = -1; AReadUntilDisconnect: Boolean = False); override;
Both are modified Indy functions that can be found in IdIOHandler.TIdIOHandler . In ReadBytes , the while clause should be replaced with a singe ReadFromSource() request, so that TryReadBytes returned after reading up to AByteCount bytes at a time.
Based on this, ReadStream should process all combinations of AByteCount (> 0, <0) and ReadUntilDisconnect (true, false) for cyclic reading, and then write to the stream pieces of data coming from the socket.
Please note that the ReadStream should not end prematurely even in this version of the stream if the juice contains only a part of the requested data. You just need to write this part to the stream instantly, and not cache it in the FInputBuffer , and then block and wait for the next part of the data.
source share