如何序列化/反序列化在Haskell中通过网络发送的对象?

时间:2014-10-21 06:49:20

标签: sockets haskell serialization

我看到有许多方法可以序列化/反序列化Haskell对象:

在我的应用程序中,我想设置一个简单的TCP客户端服务器,其中客户端可以发送序列化的Haskell记录对象。如何在这些序列化替代品之间做出决定?

此外,当使用Network.Socket通过网络发送序列化为字符串的对象时,将返回字符串。是否有一个稍高级别的库,它在整个TCP消息的级别上工作?换句话说,有没有办法避免在接收端编写解析代码:

  • 收集一系列recv()调用的结果,
  • 检测到已收到整个对象,
  • 然后将其解析为haskell类型?

在我的应用程序中,预计对象不会太大(可能大约约1MB)。

2 个答案:

答案 0 :(得分:1)

要回答问题的第一部分(关于数据序列化),我会说你列出的所有内容听起来都不错。由于你正在处理相当大的(1MB)序列化,我认为最重要的是懒惰。还有另一个序列化库,名为cereal,具有严格的序列化,您不会想要这样,因为您需要在发送之前在内存中构建它。我会向aeson(http://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson.html)大声喊叫,你可以使用GHC Generics来获得这样简单的东西:

data Shape = Rect Int Int | Circle Double | Other String Int
  deriving (Generic)
instance FromJSON Shape  -- uses a default
instance ToJSON Shape    -- uses a default

然后,bam!,您可以访问encodedecode方法。我不了解更高级别的TCP库。希望其他人对此有更深入的了解。

答案 1 :(得分:1)

关于问题的第二部分,需要做两件事:

  1. 增量解析器,它不需要将整个文档放在内存中以开始解析,并且可以使用从线路到达的部分数据块来提供。此外,当解析成功时,它必须返回任何“剩余数据”以及解析后的值。

  2. 具有“推回功能”的数据源,允许您“读取”剩余的剩余部分,以便它们可用于下一次解析尝试。

  3. 提供(1)的最受欢迎的图书馆是attoparsec。至于(2),所有三个主要流媒体库(conduitio-streamspipes)都提供某种推迟功能(后者使用辅助pipes-parse包)。所有三个库也可以与attoparsec解析器集成(请参阅hereherehere)。

    (另一种选择当然是在每个消息前面加上它的长度只读取确切的字节数。)

相关问题