You cannot rely on receiving complete messages in any communications at that low level of communication. Also you cannot rely on receiving only one message at a time.
You must implement something, that will guarantee to notify only on complete messages.
To do so you have to store the incoming data until you receive the complete message (header and finish flags).
Here is a small console app with a TMessageBuffer
class, that handles the incoming data and complete messages
program so_22436319;
{$APPTYPE CONSOLE}
{$R *.res}
uses
SysUtils;
type
TMessageBuffer = class
private
FBuffer : string;
FMsgPart : Boolean;
procedure DoHandleMessage( const CompleteMessage : string );
public
procedure AddData( const Data : string );
end;
procedure Test;
var
LMsgBuffer : TMessageBuffer;
begin
LMsgBuffer := TMessageBuffer.Create;
try
// receive complete message
LMsgBuffer.AddData( '!A243B324C213D300#' );
// receive 2 complete message in one go
LMsgBuffer.AddData( '!A243B324C213D300#!A243B324C213D300#' );
// receive parts of the message
LMsgBuffer.AddData( '!A243B324' );
LMsgBuffer.AddData( 'C213D300#!A243' );
LMsgBuffer.AddData( 'B324C213D300#!A' );
LMsgBuffer.AddData( '243B324C2' );
LMsgBuffer.AddData( '13D300#' );
finally
LMsgBuffer.Free;
end;
end;
{ TMessageBuffer }
procedure TMessageBuffer.AddData( const Data : string );
var
LIdx : Integer;
LChar : Char;
begin
for LIdx := 1 to Length( Data ) do
begin
LChar := Data[LIdx];
if FMsgPart then
if LChar = '#' then
begin
DoHandleMessage( FBuffer );
FMsgPart := False;
FBuffer := '';
end
else
begin
FBuffer := FBuffer + LChar
end
else if LChar = '!' then
begin
FMsgPart := True;
end;
end;
end;
procedure TMessageBuffer.DoHandleMessage( const CompleteMessage : string );
begin
Writeln( 'MSG: ', CompleteMessage );
end;
begin
try
Test;
except
on E : Exception do
Writeln( E.ClassName, ': ', E.Message );
end;
ReadLn;
end.
The generated output is
MSG: A243B324C213D300
MSG: A243B324C213D300
MSG: A243B324C213D300
MSG: A243B324C213D300
MSG: A243B324C213D300
MSG: A243B324C213D300
The class removes the header and finish char, because this is part of the transportation protocol and therefore not needed any more. But you can still add it if you like.