Delphi 2009, Indy 10, TIdTCPServer.OnExecute, how to capture all bytes in InputBuffer

I messed around with Indy 10 shipped with Delphi 2009, and I'm having trouble getting all the data from IOHandler when OnExecute fires ...

procedure TFormMain.IdTCPServerExecute(AContext: TIdContext); var RxBufStr: UTF8String; RxBufSize: Integer; begin if AContext.Connection.IOHandler.Readable then begin RxBufSize := AContext.Connection.IOHandler.InputBuffer.Size; if RxBufSize > 0 then begin SetLength(RxBufStr, RxBufSize); AContext.Connection.IOHandler.ReadBytes(TBytes(RxBufStr), RxBufSize, False); end; end; end; 

AContext.Connection.IOHandler.InputBuffer.Size does not seem reliable and often returns 0, but the next time OnExecute starts, it will pick the correct number of bytes, but it's too late.

Essentially, I want to be able to just grab all the data, fill it in a UTF8String (not a Unicode string), and then parse a special marker. Therefore, I have no headers, and the messages are of variable length. It seems the Indy 10 IOHandlers are not configured for this, or I'm just using it incorrectly.

It would be nice to do something like transferring a buffer of a certain size, fill it as much as possible, and return the number of bytes actually filled, and then continue if there are more.

As an aside, what is the status of TIdSchedulerOfFiber, it looks very interesting, does it work? Does anyone use it? I noticed that this is not a standard installation of Delphi 2009.

Update: I found Msg: = AContext.Connection.IOHandler.ReadLn (# 0, enUTF8); which works, but I still would like to know the answer to the above question, because it is based on IO blocking? This is even more keen on this TIdSchedulerOfFiber.

+6
delphi delphi-2009 indy
source share
2 answers

You should not use Readable (). Instead, try the following:

 procedure TFormMain.IdTCPServerExecute(AContext: TIdContext); var RxBuf: TIdBytes; begin RxBuf := nil; with AContext.Connection.IOHandler do begin CheckForDataOnSource(10); if not InputBufferIsEmpty then begin InputBuffer.ExtractToBytes(RxBuf); // process RxBuf as needed... end; end; end; 

As an alternative:

 procedure TFormMain.IdTCPServerExecute(AContext: TIdContext); var RxBufStr: String; // not UTF8String begin with AContext.Connection.IOHandler do begin CheckForDataOnSource(10); if not InputBufferIsEmpty then begin RxBufStr := InputBuffer.Extract(-1, enUtf8); // Alternatively to above, you can set the // InputBuffer.Encoding property to enUtf8 // beforehand, and then call TIdBuffer.Extract() // without any parameters. // // Or, set the IOHandler.DefStringEncoding // property to enUtf8 beforehand, and then // call TIdIOHandler.InputBufferAsString() // process RxBufStr as needed... end; end; end; 

As for TIdSchedulerOfFiber, the SuperCore package is actually dead at this time. It has not been working for a very long time and is not being updated with the latest Indy 10 architecture. We may try to resurrect it later, but this is not in our plans for the near future.

+16
source share
 procedure TFormMain.IdTCPServerExecute(AContext: TIdContext); var RxBufStr: UTF8String; RxBufSize: Integer; begin if AContext.Connection.IOHandler.Readable then begin AContext.Connection.IOHandler.ReadBytes(TBytes(RxBufStr),-1, False); end; end; 
+1
source share

All Articles