c++ - 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).
解决方案
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
您选择的值传递给它。
就个人而言,我不建议在同一台服务器上混合使用文本和非文本客户端。它们显然使用不同的协议,因此您应该在不同的端口上使用不同的服务器来分别处理它们。
推荐阅读
- reactjs - 如何使用 React 测试库为 useMutation 编写测试用例?
- c# - 在 Swagger 中生成响应错误 - .netCore Api
- java - 去除双向链表中的头部
- visual-studio-code - 为什么当我使用这个 textMate 时 VSCode 不突出显示任何内容?
- vue.js - Vuejs - 查找未使用的道具。事件和组件
- amazon-web-services - 如何将现有的 vpc 用于不同的项目?
- c# - 如何将选定的数据从网格传递到另一个空网格,然后将其存储在数据库表中?
- c - 简化递归函数
- api - API 如何与应用程序服务器一起工作?
- hyperledger-fabric - 即使没有发生内存密集型操作,对等容器也会消耗过多内存