【问题标题】:Erlang get_tcp:recv data lengthErlang get_tcp:recv 数据长度
【发布时间】:2011-07-02 03:57:08
【问题描述】:

我使用gen_tcp:recv(Socket, 0). 接收数据,但我只能接收 1418 字节 1 次。我如何才能收到发送的数据量?

【问题讨论】:

  • 这个问题可能会有所帮助:Limitation of the reception buffer.
  • 我投票结束这个问题,因为类似的问题每两周出现一次。
  • 虽然在这种情况下略有不同,但请注意。即使他们不时出现。

标签: sockets erlang


【解决方案1】:

gen_tcp:recv(Socket, 0) 中,您在询问内核:“给我接收缓冲区中现在可用的所有数据”。内核也可以免费为您提供更少的内容。即使对于一个相当快的链接,您可能会在 TCP 连接上点击 slow start,所以一开始您不会获得太多数据。

解决方案是自己做缓冲。您将不得不从底层套接字中获取数据,直到您有足够的时间来构造消息。因此,二进制协议在流之上实现自己的消息传递是很常见的。


对于长期记录:常见的消息格式是将消息编码为:

decode(Bin) when is_binary(Bin) ->
  <<Len:32/integer, R/binary>> = Bin,
  <<Payload:Len/binary, Remain/binary>>,
  {msg, {Len, Payload}, Remaining}.

也就是说,消息是 4 个字节,表示一个 32 位 bigendian 整数,后跟有效负载,其中长度由整数给出。这种格式和其他类似的格式非常常见,Erlang 直接在 C 层中包含针对它的优化解析器。要访问这些,您可以通过inet/setops/2 在套接字上设置选项,在我们的例子中,我们设置{packet, 4}。然后我们可以通过在socket上设置{active, once}来获取消息,等待下一条消息。当它到达时,我们可以再次在套接字上{active, once} 以获取下一条消息,依此类推。 gen_tcp 的文档中有一个示例(erl -man gen_tcp,如果您正确安装了 Erlang 手册页)。

其他常见格式是 asn.1 甚至是 http headers(!)。

技巧

创建一个可以对消息格式进行编码和解码然后将数据发送到系统其余部分的独立进程通常是有益的。通常在 Erlang 中一个好的解决方案是尽可能快地对传入的数据进行解复用,并将数据发送到一个进程,然后该进程可以处理剩下的问题。

【讨论】:

  • 很好的答案,这些问题不断出现的问题是 TCP 被误解为基于消息的协议。如果将其视为可靠的串行线路,它会变得更加清晰。
  • 我倾向于同意。另请注意,SCTP 可能是用于消息的正确协议,但遗憾的是,似乎没有人关心它:/
猜你喜欢
  • 2011-12-23
  • 2017-06-23
  • 1970-01-01
  • 2012-02-27
  • 2011-01-20
  • 2015-03-23
  • 2017-10-07
  • 1970-01-01
  • 2014-06-05
相关资源
最近更新 更多