I have a TCP server in my Windows application based on TIdCmdTCPServer
and it has been performing great. Now I have a device that does not send text string but binary data. I really don't want to rewrite my working code to use TIdTCPServer
.
Is there any way I can use my current code and grab the discarded data somewhere, i.e. can I have access to the raw data received without interfering with other connections that use text?
I tried the OnBeforeCommandHandler
event, but it already seems to assume the data is a string (i.e. cuts off at the first zero byte).
TIdCmdTCPServer
does not stop reading on nul bytes, like you claim. By default, it reads each command by calling TIdIOHandler.ReadLn()
, which reads until a (CR+)LF
is received. However, the TIdIOHandler.DefStringEncoding
is set to US-ASCII by default, so that could be causing data loss when reading binary data as a string.
That being said, TIdCmdTCPServer
is designed primarily for textual commands. By default, tt cannot receive binary commands, or binary parameters. However, if the binary data follows a textual command, your TIdCommandHandler.OnCommand
event handlers can read the binary data after the command has been received, by simply reading the binary using the ASender.Context.Connection.IOHandler
as needed.
Otherwise, if that does not suit your needs (because the binary commands are not in a format that would normally trigger an OnCommand
event), you will have to derive a new class from TIdCmdTCPServer
and have it either:
override the virtual ReadCommandLine()
method to read a binary command and its parameters from the Connection
and return that data in a string
format of your choosing (you can use Indy's IndyTextEncoding_8bit
encoding, or BytesToStringRaw()
function, to help you with that, or use whatever string
format you want). And then define a CommandHandler
to match that stringified command.
override the virtual DoExecute()
method, then you have full control over the reading of the Connection
and can handle commands however you want. To trigger OnCommand
events, call the server's CommandHandlers.HandleCommand()
method passing it string
values of your choosing.
Personally, I would not recommend mixing textual and non-textual clients on the same server. They are clearly using different protocols, so you should be using different servers on different ports to handle them separately.