I am always struggling with this whenever I try to throw together a TCP client application...
I can easily send commands to the server (in this case a WiFi IoT module.
I know it responds to the command but for the life of me I cannot get the reply.
The platform I use is 64 bit FreePascal 3.0.4 + Lazarus 1.8.0 with the IndyLaz package installed
THe function that fails to work as I hoped looks like this (FComm is a TIdTcpClient object):
For example what happens if this ReadBytes function does not get all of the incoming bytes?
I try to detect it via the ETX check but since the data is only at maximum some 25-40 bytes (not possible to know beforehand) I thought it highly unlikely it would be split between packets...
I found the cause regarding this specific problem:
The server did not add the trailing ETX to replies, so all of them were thrown away.
I modified the server code to always add the ETX to all outgoing messages.
But I have a follow-up question:
How can the PC application be made such that it will catch and display all incoming data without first sending a command?
For example spontaneous messages from the device are also interesting...
I can easily send commands to the server (in this case a WiFi IoT module.
I know it responds to the command but for the life of me I cannot get the reply.
The platform I use is 64 bit FreePascal 3.0.4 + Lazarus 1.8.0 with the IndyLaz package installed
THe function that fails to work as I hoped looks like this (FComm is a TIdTcpClient object):
Code:
function TConfigCommHandler.GetItem(Cmd: TIdBytes; var Data: TIdBytes): boolean;
begin
Result := false;
SetLength(Cmd, Length(Cmd) + 1);
Cmd[Length(Cmd)-1] := ETX;
FComm.IOHandler.ReadTimeout := 2000;
try
FComm.IOHandler.Write(Cmd);
SetLength(Data, 0);
FComm.IOHandler.ReadBytes(Data, -1, false); //<== Is this way correct?
Result := Length(Data) > 0;
if Result then
begin
if Data[Length(Data)-1] <> ETX then //Received packet should end in ETX...
begin
FLastError := 'Terminating ETX missing!';
Result := false;
end
else
SetLength(Data, Length(Data) -1); //Remove trailing ETX
end
else
FLastError := 'No data received within timeout!';
except
on E: Exception do
begin
Result := false;
FLastError := 'Exception: ' + E.Message;
Exit;
end;
end;
end;I try to detect it via the ETX check but since the data is only at maximum some 25-40 bytes (not possible to know beforehand) I thought it highly unlikely it would be split between packets...
I found the cause regarding this specific problem:
The server did not add the trailing ETX to replies, so all of them were thrown away.
I modified the server code to always add the ETX to all outgoing messages.
But I have a follow-up question:
How can the PC application be made such that it will catch and display all incoming data without first sending a command?
For example spontaneous messages from the device are also interesting...



Then you have the added burden of detecting when an incoming message is a reply to a previous command vs an unsolicited message. And almost always requires you to code your app to work asynchronously, unlike the code above which is synchronous. When you send a command, you would not be able to wait for the reply, you would have to exit and move on, and let your separate reading loop receive the eventual reply and decide what to do with it, in addition to any unsolicited messages it may also receive.