首页 > 解决方案 > Use TIdCmdTCPServer for binary data?

问题描述

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).

标签: c++c++builderindyindy10

解决方案


TIdCmdTCPServer不会像您声称的那样停止读取 nul 字节。默认情况下,它通过调用读取每个命令TIdIOHandler.ReadLn(),直到(CR+)LF收到 a 为止。但是,TIdIOHandler.DefStringEncoding默认情况下设置为 US-ASCII,因此在将二进制数据作为字符串读取时可能会导致数据丢失。

话虽这么说,TIdCmdTCPServer主要是为文本命令设计的。默认情况下,tt 无法接收二进制命令或二进制参数。但是,如果二进制数据遵循文本命令,您的TIdCommandHandler.OnCommand事件处理程序可以在收到命令后读取二进制数据,只需ASender.Context.Connection.IOHandler根据需要使用读取二进制文件即可。

否则,如果这不符合您的需要(因为二进制命令不是通常会触发OnCommand事件的格式),您将不得不从中派生一个新类TIdCmdTCPServer并拥有它:

  • 覆盖虚拟ReadCommandLine()方法以从 中读取二进制命令及其参数,Connection并以您选择的格式返回该数据string(您可以使用 Indy 的IndyTextEncoding_8bit编码或BytesToStringRaw()函数来帮助您,或使用string您想要的任何格式)。然后定义 aCommandHandler以匹配该字符串化命令。

  • 覆盖虚拟DoExecute()方法,然后您可以完全控制读取Connection并可以根据需要处理命令。要触发OnCommand事件,请调用服务器的CommandHandlers.HandleCommand()方法,将string您选择的值传递给它。

就个人而言,我不建议在同一台服务器上混合使用文本和非文本客户端。它们显然使用不同的协议,因此您应该在不同的端口上使用不同的服务器来分别处理它们。


推荐阅读