将 TIdCmdTCPServer 用于二进制数据?

Use TIdCmdTCPServer for binary data?

我的 Windows 应用程序中有一个基于 TIdCmdTCPServer 的 TCP 服务器,它运行良好。现在我有一个不发送文本字符串但发送二进制数据的设备。我真的不想重写我的工作代码来使用 TIdTCPServer.

有什么方法可以使用我当前的代码并在某处获取丢弃的数据,即我可以访问接收到的原始数据而不干扰其他使用文本的连接吗?

我尝试了 OnBeforeCommandHandler 事件,但它似乎已经假设数据是一个字符串(即在第一个零字节处截断)。

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

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

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

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

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

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