【问题标题】:Parsing JSON data from TCP stream从 TCP 流中解析 JSON 数据
【发布时间】:2021-07-07 10:28:18
【问题描述】:

我正在使用 nlohmann 的 json 库来解析来自 TCP 流的 json 数据。我不太确定如何处理从本地套接字读取的部分 json。假设在第一次 read() 中我得到:

{ 
    "MessageType": "CancelOrder",
    "Account":11111, 
    "CustomerNo":11111,
    "Side":"A",
    "DestinationMarket":"DUMB_MARKET",
    "Symbol":"DUMB_SYMBOL",
    "PositionEffect":"D",
    "Limi

在下面来自套接字的 read() 中,我得到:

    tPrice":0,
    "Quantity":1,
    "OrderType":"DUMB_TYPE",
    "StopPrice":0,
    "TimeInForce":"01.06.1999",
    "ExpireDate":0,
    "OrderID": "DUMB_ID",
    "IsStopOrder":"DUMB_STOP",
    "CorrelationId": 456
}

库无法解析部分读取,因为它们无效。图书馆是否提供解决方案?还是我应该自己实施解决方案?

这里的最佳做法应该是什么?

【问题讨论】:

  • 一个可行的解决方案是在单独从套接字读取之后合并所有字符串,直到在字符串末尾找到尾随 }。然后,您可以继续处理 JSON。
  • 低延迟的应用不要使用JSON相关的RPC(其实也没有好的工业级技术方案),建议试试grpc或者fbthrift。
  • content 之前发送length,例如HTTP 标头。
  • 一个潜在的解决方案是在每次读取时获取尽可能多的有效键,并在它们之后插入},解析它们,然后当更多键出现时重复并合并对象一起。我不确定这会是什么性能,但我怀疑没有比按照@Ruks 建议的那样连接所有数据好多少。
  • 我参与了一个使用 JSON over IPC 的项目。如果您确实无法使用这种数据格式,我有几个建议 - 1. 使用面向消息的 IPC 库而不是原始 TCP。我们使用 ZeroMQ,保证我们不会收到这样的部分消息。 2. 如果可能,不要将数据发送为字符串化的 JSON。由于频繁的字符串双转换,我们遇到了数值数据的主要性能问题。如上所述,JSON 以外的其他东西可能更好。但有时你必须做你必须做的。

标签: c++ json stream nlohmann-json


【解决方案1】:

您在 cmets 中得到了一些很好的答案。我将组装一些并添加更多选择。

如果您可以控制通信的两端,那么有些人认为您应该通过以下两种方式之一更改通信:

  • 先发送文本长度
  • 或者在套接字上使用更智能的消息传递系统

其中任何一个都可以为您解决问题。

我将提供另外两种可能的选择。

  • 发送一个“数据结束”指示符——它不会出现在 JSON 中。例如,一个空字节。在 EOD 字符之前中断。
  • 尝试依次解析数据,直到解析成功。

第二个有点丑。你会解析{ 并得到一个异常。然后你会一遍又一遍地解析{" 的异常,直到你最终拥有完整的 JSON。我敢打赌它很慢,但它可能会起作用,而且它不依赖于以任何方式更改数据流。

就个人而言,我会按顺序考虑:

  1. 使用适当的消息传递协议
  2. 使用数据结束指示符
  3. 发送长度
  4. 在解析之前解析和捕获异常的技巧

我认为其中任何一个都可以。最后一个是唯一不强制您更改数据流两端的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 2015-02-02
    • 1970-01-01
    • 2015-05-29
    • 1970-01-01
    • 2022-11-10
    相关资源
    最近更新 更多